foakesm
foakesm

Reputation: 933

Return a name through an API call in React.js

using React.js I am trying to display the artist names that are given through an API call.

I have a class component called ArtistList that is being called on my main index.js page, and I'm trying to use the artist usernames in the API data to update the component's state.

No matter what I try I seem to keep getting the same error message with this in my browser console:

Uncaught TypeError: this.state.artist.map is not a function

import React, { Component } from 'react';
import axios from 'axios';

class ArtistList extends Component {
  constructor(props) {
   super(props);

   this.state = {artist: []};
 }

 componentDidMount() {
   this.ArtistList();
 }

 ArtistList() {
   axios.get('https://api-v2.hearthis.at/feed/?type=popular&page=1&count=20')
     .then((data) => this.setState({ artist: data }));
 }

 render() {
   const artists = this.state.artist.map((item) => (
     <div>
       <h1>{ item.user.username }</h1>
     </div>
   ));

   return (
     <div className="layout-content-wrapper">
       <div className="panel-list">{ artists }</div>
     </div>
   );
 }
}

Upvotes: 0

Views: 409

Answers (4)

Singh
Singh

Reputation: 1988

Try this

class ArtistList extends React.Component {
    constructor(props){
       this.state = {
          artist: [];
       }
    }
    async componentDidMount() {
        const res = await axios.get('https://api-v2.hearthis.at/feed/?type=popular&page=1&count=20');
        const artist = await res.data;
        this.setState({artist});
    }
    renderArtists = () => {
        if(this.state.artist.length!=0){
            return this.state.artist.map(item => {
                return (
                   <div>
                     <h1>{ item.user.username }</h1>
                   </div>
                )
            });
        }
    }
    render(){
        return (
           <div className="layout-content-wrapper">
             <div className="panel-list">{this.renderArtist()}</div>
           </div>
        )
    }
}

Upvotes: 0

Gautam
Gautam

Reputation: 825

Here is the working code(your code looks fine), your axios's API is having some problem.

https://jsfiddle.net/RanjeetKumarGautam/69z2wepo/183143/

class ArtistList extends React.Component {
  constructor(props) {
   super(props);

   this.state = {artist: []};
 }

 componentDidMount() {
   this.ArtistList();
 }

 ArtistList() {
   this.setState({ artist: [{user:{username: 'john'}},{user:{username: 'ken'}}] });
 }

 render() {
   const artists = this.state.artist.map((item) => (
     <div key={item.user.username}>
       <h1>{ item.user.username }</h1>
     </div>
   ));

   return (
     <div className="layout-content-wrapper">
       <div className="panel-list">{ artists }</div>
     </div>
   );
 }
}

Upvotes: 0

Andy Fusniak
Andy Fusniak

Reputation: 1638

The axios Promise resolves to be a response object. The data property contains the payload. Try this:

axios.get('https://api-v2.hearthis.at/feed/?type=popular&page=1&count=20')
  .then((response) => this.setState({
    artist: response.data
  }));

Upvotes: 1

Roy Wang
Roy Wang

Reputation: 11270

axios's API returns a response object with data being one of the properties, so change it to

axios.get('https://api-v2.hearthis.at/feed/?type=popular&page=1&count=20')
  .then(({ data }) => this.setState({ artist: data }));

Upvotes: 3

Related Questions