I created this React application to practice the fetch API. However, while writing the code to display the data on the browser via the map method, I got the error message "TypeError: profile.map is not a function". Below is the code:
import React, { Fragment, useEffect, useState } from "react";
import "./App.css";
function App() {
// https://reqres.in/api/users
const [profile, setProfile] = useState([]);
const [loading, setLoading] = useState(false);
const getProfile = async () => {
setLoading(true);
const response = await fetch("https://reqres.in/api/users");
const data = await response.json();
setProfile(data);
setLoading(false);
};
useEffect(() => {
getProfile();
}, []);
return (
<Fragment>
<h1>React fetch</h1>
<div className="main">
<section className="section">
<h2>Get database</h2>
<div>
{loading ? (
<Fragment>loading..</Fragment>
) : (
profile.map(i => {
<Fragment>
<ul>
<li>{i.id}</li>
<li>{i.email}</li>
<li>{i.first_name}</li>
<li>{i.last_name}</li>
<li>
<image src={i.avatar} />
</li>
</ul>
</Fragment>;
})
)}
</div>
</section>
<form className="section">
<h2>Post data</h2>
<input type="text" placeholder="enter detail" />
<button type="submit">Post</button>
</form>
<form className="section">
<h2>Update data</h2>
<select>
<option>Choose data</option>
</select>
<input type="text" placeholder="enter detail" />
<button type="submit">Update</button>
</form>
</div>
</Fragment>
);
}
export default App;
Why isn't map being recognized?
CodePudding user response:
So, const data = await response.json();
After this line is executed the result we are getting inside the data constant is an Object. We can use MAP function only on Array's, not on Objects. And also the Profile data which you are actually searching is inside the "data" key of the data "constant". So while setting profile data, just use setProfile(data.data);
. It will do the work for you.
A suggestions: Use this Chrome Extension for viewing the API data. It indents the json objects automatically
Happy Coding!
CodePudding user response:
I believe it's because .map is a method for Array prototypes, not for Objects (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
You can return the array from the object by using data.data instead of just data:
...
const getProfile = async () => {
setLoading(true);
const response = await fetch("https://reqres.in/api/users");
const data = await response.json();
setProfile(data.data); // probably a safer way to do this, but if you console.log(data) you'll see an object is being returned, not an array.
setLoading(false);
};
...
CodePudding user response:
Map needs to return a value.
{loading ? (
<Fragment>loading..</Fragment>
) : (
profile.map(i => {
return (
<Fragment>
<ul>
<li>{i.id}</li>
<li>{i.email}</li>
<li>{i.first_name}</li>
<li>{i.last_name}</li>
<li>
<image src={i.avatar} />
</li>
</ul>
</Fragment>;
)
})
)}
Also, you cannot use the map function on an object. It looks like your response is an object, what you are looking for is the data from the response. Try this...
setProfile(data.data);