mcw mcw - 1 month ago 6
Ajax Question

Debugging live search bar in ReactJS

I'm developing a Rails app that draws data via an AJAX call to Spotify's API and renders that data via a live search bar that I've created using ReactJS.

My top component is titled SearchController and that's where the AJAX call is made and set to data based on the search text the user is inputting. That data is then passed down into two smaller components SearchBar and SearchResultsList.

My issue arrises in rendering the results in the SearchResultList component.

Here's my code:

class SearchResultsList extends Component {
render(){
return (
<ul className="dropdown-menu" id="autocomplete-items">
{this.renderAlbums()}
</ul>
);
};

renderAlbums(){
if (this.props.albums === undefined) {
return ''
} else {
return (
<ul>
<div className="dropdown-item">{this.props.albums.albums.items[0].name}</div>
<div className="dropdown-item">{this.props.albums.albums.items[1].name}</div>
<div className="dropdown-item">{this.props.albums.albums.items[2].name}</div>
<div className="dropdown-item"><a href="/albums/new">Or add it yourself</a></div>
</ul>
);
};
};
}


While it's functional, I'm running into a specific issue in that if the call only returns 1 or 2 results instead of the full 3 spaces specified in the renderAlbum return it raises an error.

There is an total result integer being returned in my this.props.album block of data and I feel as if that could be useful in terms of looping through the data and perhaps setting the integer I'm calling on each dropdown-item so as to return as many results as I'm actually getting from my Ajax call.

Anyway, any help would be appreciated. Not as sharp with JavaScript as Ruby and though I feel like I'm on the right track I could definitely use a hand.

Answer

instead of returning a <ul> which always assumes it will have 3 children, why not turn each object in this.props.albums.albums.items into a <li> directly (don't use <div>, it's not proper HTML here)?:

<ul>
  {this.props.albums.albums.items.map(function(album) {
     return (
       <li className="dropdown-item">
         {album.name}
       </li>
     );
  })}
  <li>Or add it yourself</li>
</ul>

this will work for arrays with any number of items.