I'm struggling since two days on this and afters hours of trial and error I couldn't solve it.
What I'm trying to achieve is that I can display my fetched data, which I get from my backend. I saw several example on different websites, but I can't get it to work.
Here is my code and the error I get:
function Tours({ isAuth: isAuth, component: Component, ...rest }) {
const [listOfTours, setListOfTours] = useState([]);
console.log(listOfTours);
const getAllTours = () =>
axios
.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
})
.then((response) => {
if (response.data.status === "error") {
console.log(response.data.status);
} else {
setListOfTours(response.data);
}
});
useEffect(() => {
getAllTours();
}, []);
if (listOfTours.length > 0) {
return (
<div>
<div className="tourDisplay">
{listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
</div>
);
} else {
return (
<div>
<p>Loading...</p>
</div>
);
}
}
export default withRouter(Tours);
TypeError: listOfTours.map is not a function
Tours
src/components/tours.js:32
29 | if (listOfTours.length > 0) {
30 | return (
31 | <div>
> 32 | <div className="tourDisplay">
| ^ 33 | {listOfTours.map((tour) => {
34 | return (
35 | <div>
I think it has something to do with the asynchronous call and that .map can't process with empty array. Therefor, I use the if statement in front of the return, but it also won't work.
Does someone have any idea, or am I missing something?
Try to make the getAllTours
function as a Promise.
...
const [listOfTours, setListOfTours] = useState(null);
const getAllTours = async () => {
try {
// not sure if /api/all-tours is the proper API source
const tours = await axios.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
});
// try to console.log here to make sure if the tours has responded successfully and what type of the tours.response.data has either object or array
console.log(tours.response);
console.log(typeof tours.response.data);
// this seems to be tours.response without data
if (tours.response.data) { // if (tours.response) {
// if tours.response.data is a type string, then convert it to json object
// setListOfTours(JSON.parse(tours.response.data));
setListOfTours(tours.response.data);
// setListOfTours(tours.response);
}
} catch (err) {
console.error(err);
}
}
useEffect(() => {
getAllTours();
}, [getAllTours]);
return (
<div>
{
!listOfTours
? // loading div
: <div className="tourDisplay">
{listOfTours.length > 0 && listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
}
</div>
);
If this doesn't work, please inspect the browser and go to the network tab, and then make sure the API worked properly.