Reputation: 25
I'm trying to render elements from a map function however it does not seem to be working. I have tried to change the return but nothing seems to work.
class API extends Component {
myTop10Artists() {
Api.getMyTopArtists(function (err, data) {
if (err) {
console.error(err);
} else {
console.log(data.items);
return data.items.map((artist) => {
console.log("artist name " + artist.name);
console.log("artist id " + artist.id);
console.log("artist popularity " + artist.popularity);
return (
<div key={artist.id} className="card">
<div key={artist.id} className="cardContent">
<h3> {artist.name} </h3>{" "}
</div>{" "}
</div>
);
});
}
});
}
render() {
return <div className="cardsWrap"> {this.myTop10Artists()} </div>;
}
}
Upvotes: 1
Views: 1420
Reputation: 1
1-use map function inside your return
2-use round braces instead of curly braces to surround your arrow function
return ({data.items.map((artist) => (
<div key={artist.id} className="card">
<div key={artist.id} className="cardContent">
<h3> {artist.name} </h3>{" "}
</div>{" "}
</div>
))};
);
Upvotes: 0
Reputation: 5002
Store items
in state and update it with the api response. This will cause your component to rerender.
Also, move your api call to component hook
componentDidMount(){
Api.getMyTopArtists(function (err, data) {
this.setState({
items: data.items
})
}
Upvotes: 1
Reputation: 455
This won't work, because you are returning your data from a callback, instead you need to store using this.setState()
the fetched data into your state and then display it.
class API extends Component {
constructor(props){
super(props);
this.state = {
data: null,
error: null
}
this.myTop10Artists = this.myTop10Artists.bind(this);
}
componentDidMount(){
this.myTop10Artists();
}
myTop10Artists() {
Api.getMyTopArtists(function (err, data) {
if (err) {
this.setState({...this.state, error: err});
} else {
this.setState({error: null, data})
}
});
}
render() {
const {error, data} = this.state;
if(error){
return <div>Error! Try again</div>
}
if(!data){
return <div>Loading..</div>
}
return (
<div>
data.items.map((artist) => (
<div key={artist.id} className="card">
<div key={artist.id} className="cardContent">
<h3> {artist.name} </h3>{" "}
</div>{" "}
</div>
))
</div>
)
}
}
Upvotes: 1
Reputation: 1547
Just an idea of how to do approach this another way with hooks and functional components. Main issue in your code, as mentioned by others already, is the fact that the results are not returned by the callback or set to a state.
const MyTop10Artists = () => {
const [artists, setArtists] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState();
useEffect(() => {
Api.getMyTopArtists((err, data) => {
if (err) {
console.error(err);
setError(err);
return;
}
setArtists(data.items);
setIsLoading(false);
});
}, []);
return (
<>
{isLoading && "Loading"}
{error && error}
{!isLoading && artists.length === 0 && "No artists"}
{!isLoading &&
artists.map((artist) => (
<div key={artist.id} className="card">
<div key={artist.id} className="cardContent">
<h3>{artist.name}</h3>
</div>
</div>
))}
</>
);
};
const API = () => (
<div className="cardsWrap">
<MyTop10Artists />
</div>
);
Upvotes: 1