1

So I am trying to make it so when you click the search button, it displays all the artist's names but when I click search nothing happens. When I do

console.log(artistsArray.name);

it gives me a list of all the artist's names for the search query so I'm not sure what I am missing; I am also new so sorry if I didn't explain well.

this is my search function

  searchAlbums(){
    spotifyWebApi.searchAlbums(this.state.value)
    .then((response) => {
      return response.albums.items.map((t) => {
        return t.artists.map((artistsArray, index) => {
          this.render({
            render(){
              return (
                <div>
                <li key={artistsArray.name}>
                  {artistsArray.name}
                </li>
                </div>
              )
            }
          })
        });
      });
    });
  }

and here is the button

<button class="btn btn-small" type="button" onClick={() => this.searchAlbums()}>Search</button> 
2
  • There are a few issues here. A good place to start would be just having the result of your call just update state or props. The render function belongs to the component, not to your response. Check this out: blog.hellojs.org/fetching-api-data-with-react-js-460fe8bbf8f2 Commented Jul 19, 2018 at 2:21
  • why didn't post all your code ? I mean your whole file ex: index.js Commented Jul 19, 2018 at 2:36

2 Answers 2

1

You need to render a list of components in render() function.
Not render multiple times for each album.

Here is how you might render a list of album artists.
1. Declare the state to hold albums (an empty array by default) retrieved.
2. On handleSearchClick, retrieve albums and set the albums state.
3. In render(), if album is not found, then display appropriate messages.
4. else create a list of artist components (wrapped in <li>).
5. Display the component by returning it.

⚠️ WARNING: this is not a production/clean code.

class SearchResult extends React.Component {
    state = { albums: [] };

  searchAlbums = async (searchValue) => (await spotifyWebApi.searchAlbums(searchValue));

  handleSearchClick = async (e) => {
    const searchValue = e.target.value;
    const {items: albums} = await this.searchAlbums(searchValue);
    this.setState({albums});
  }

  render() {
    const {albums} = this.state;
    if (!album) return <div>loading...</div>;
    if (album.length === 0) return <div>No albums found</div>;

    // Generate artists components.
    const albumsComponents = albums.map(album => 
        album.artists.map(artists => (<li key={artists.name}>{artists.name}</li>)
    }

    return (
      <div>
        Search Term: 
        <input 
          value={this.state.searchTerm}
          onClick={this.handleSearchClick} />
        {albumsComponents}
      </div>
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

For now you're doing it in reverse. You have to map albums array inside of render function, not iside of a searchAlbums. What you can do, is to place albums array inside of state:

constructor(){
    super();
    this.state = {
        albums: []
    }
}

and in searchAlbums function set it in that state:

searchAlbums(){
  spotifyWebApi.searchAlbums(this.state.value)
    .then((response) => {
      this.setState({albums: response.albums.items});
    });
}

after that, in render function map it, like you did:

render(){
    return this.state.albums.map((t) => {
       return t.artists.map((artistsArray, index) => {
          return (
            <div>
            <li key={artistsArray.name}>
              {artistsArray.name}
            </li>
            </div>
          )
       });
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.