'How to fix "TypeError: results.map is not a function", in React
function Results(props) {
var results = props.results;
return (
<>
<table>
<thead>
<tr>
<th>Book Name</th>
<th>Author</th>
<th>S.no</th>
<th>Series Name</th>
<th>Type</th>
<th>Genre</th>
<th>Kindle/Real</th>
</tr>
</thead>
<tbody>
{results.map(result => {
return (
<tr key={result.name}>
<td>{result.name}</td>
<td>{result.author}</td>
<td>{result.sno}</td>
<td>{result.series}</td>
<td>{result.type}</td>
<td>{result.genre}</td>
<td>{result.kindeReal}</td>
</tr>
);
})}
</tbody>
</table>
</>
);
}
When I try to render the above com component, I get the error:
TypeError: results.map is not a function
The results variable is an array of objects, something like:
[{"type":1},{"type":0},{"type":2}]
However, when I use the .map function, it returns the error! It is clearly an array, so why can't I use it?
This is the output of console.log(results).
[{"Book_Name":"Time Riders","Author":"Alex Scarrow","S_no":1,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Day of the Predator ","Author":"Alex Scarrow","S_no":2,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Doomsday Code","Author":"Alex Scarrow","S_no":3,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Eternal War","Author":"Alex Scarrow","S_no":4,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Gates of Rome","Author":"Alex Scarrow","S_no":5,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"City of Shadows","Author":"Alex Scarrow","S_no":6,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Pirate Kings","Author":"Alex Scarrow","S_no":7,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Mayan Prophecy","Author":"Alex Scarrow","S_no":8,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Infinity Cage","Author":"Alex Scarrow","S_no":9,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"}]
It looks like an array to me. Why is it not an array then?
This is the parent component.
import React from "react";
import Results from "./results";
function ResultsRenderer(props) {
if (props.status === true) {
return <Results results={props.results} />;
} else {
return <>{"No"}</>;
}
}
export default ResultsRenderer;
This is the parent component of ResultsRenderer.
import React, { useState } from "react";
import { useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Form from "./searcherFormDumb";
import { toast } from "react-toastify";
import ResultsRenderer from "./resultsRenderer";
function Searcher() {
const [answer, setAnswer] = useState(["Empty", false]);
const [book, setBook] = useState({
name: "",
author: "",
sno: null,
series: "",
type: "",
genre: "",
kindleReal: ""
});
const defaultState = {
name: "",
author: "",
sno: null,
series: "",
type: "",
genre: "",
kindleReal: ""
};
function handleChange(event) {
const updatedBook = { ...book, [event.target.name]: event.target.value };
setBook(updatedBook);
}
function handleSubmit(event) {
event.preventDefault();
var changed = {};
function populateChanged(now, old, title, temp) {
if (now !== old) {
temp[title] = now;
return temp;
} else {
return temp;
}
}
changed = populateChanged(
book.name,
defaultState.name,
"Book_Name",
changed
);
changed = populateChanged(
book.author,
defaultState.author,
"Author",
changed
);
changed = populateChanged(book.sno, defaultState.sno, "S_no", changed);
changed = populateChanged(
book.series,
defaultState.series,
"Series_Name",
changed
);
changed = populateChanged(
book.type,
defaultState.type,
"Fiction_Non_fiction_Companion_Prequel",
changed
);
changed = populateChanged(book.genre, defaultState.genre, "Genre", changed);
changed = populateChanged(
book.kindleReal,
defaultState.kindleReal,
"Kindle_Real",
changed
);
var temp_string = "";
var key = "";
var value = "";
var temp_string_list = [];
//debugger;
for (var i = 0; i < Object.keys(changed).length; i++) {
//debugger;
key = Object.keys(changed)[i];
value = changed[key];
if (i !== Object.keys(changed).length - 1) {
temp_string = `${key} = "${value}" AND `;
} else if (i === Object.keys(changed).length - 1) {
temp_string = `${key} = "${value}"`;
}
temp_string_list.push(temp_string);
//debugger;
temp_string = "";
key = "";
value = "";
}
var sql_t = temp_string_list.join("");
var sql_tt = "SELECT * FROM books_catalouge WHERE ";
var sql = sql_tt + sql_t;
toast.success(sql);
var request = new XMLHttpRequest();
var jsql = JSON.stringify(sql);
request.onreadystatechange = function() {
//debugger;
if (this.readyState == 4 && this.status == 200) {
setAnswer([this.responseText, true]);
console.log(`${answer}`);
}
};
request.open(
"GET",
"http://localhost:3001/retrieve_books" + "?msg=" + jsql,
true
);
request.send(jsql);
console.log("This is the END");
console.log(`${answer}`);
}
return (
<>
<Form book={book} onChange={handleChange} onSubmit={handleSubmit} />
<br />
<ResultsRenderer status={answer[1]} results={answer[0]} />
</>
);
}
export default Searcher;
Let me know if you need the NodeJS as well. I am using SQL to get the data, which is why I need the NodeJS. Sorry if my code is a little weird.
Thanks in advance!
Solution 1:[1]
I'm seeing similar behavior when deserializing a simple .json file:
const stringifiedData = fs.readFileSync(animalsPath);
const animalData = JSON.parse(stringifiedData);
const animals = animalData.map(animal => {
return new Animal(animal)
})
Oddly, the example I'm following is doing a string dot notation that seems to satisfy V8 that the object is an array, even though it's output in console.out does not change. The following does work but I don't know why. Any ideas?
const stringifiedData = fs.readFileSync(animalsPath);
const animalData = JSON.parse(stringifiedData).animals;
const animals = animalData.map(animal => {
return new Animal(animal)
})
Solution 2:[2]
I also got the same error while accessing data element of an array. here is what I did:
{standardObj ? (
{standardObj.map((obj: any) => {
return (
<Grid item>
<FormControlLabel
className={styles.CheckboxLabel}
key={obj.Code}
control={
<Checkbox
onChange={handleCheckElement}
name={obj.FullName}
value={obj.Code}
/>
}
label={obj.FullName}
/>
</Grid>
);
})}
) : null }
Solution 3:[3]
I faced the same problem and appars that for the useState Hook is very important the type of data of the inital value, I had as initial value a 0 int and cos that react didn't recognize the update as array.
Solution 4:[4]
Most of the time this problem is because of wrong syntax.
where there is
results.map(result => {
........................
}
just do
results.map(result => (
........................
)
Solution 5:[5]
I am new to React and found out that if a variable is empty / undefined and used with "map" function, the React throws that exception. My solution was to check a variable for "undefined" and length > 0.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jack Mason |
| Solution 2 | Jay |
| Solution 3 | Guillermo Piedrabuena |
| Solution 4 | |
| Solution 5 | mandroid |
