1

How do I iterate one index at a time in the array 'tracks' in react jsx. I want to be able to iterate and display just one track at a time in the array, and go to the next track (index) on the click of a button that'll be labeled 'Next', also go back to previous index when clicking the button 'Previous'.

  constructor(props){
     super(props);
     this.state=({
        year: (props.location.state && props.location.state.year) || '',
        all_tracks: {tracks:[]},
        currentTrack: 0,
     });
  }
  onClickNext(){ //Next button
      //Nothing done here yet
  }
  onClickPrev(){ //Previous button
      //Nothing done here yet
  }
  render(){
    const {
      currentTrack,
      all_tracks: { tracks }
    } = this.state;
    return (
        window.addEventListener('DOMContentLoaded', (event) => { 
            this.gettingTracks() //Have tracks load immediately
        }),
       <div id = "song"> //THIS PART
              <iframe id="track" src={tracks[currentTrack]
                           ? "https://open.spotify.com/embed/track/"+tracks[currentTrack].id
                           : "Song N/A"} ></iframe>
       </div>
       <div>
            <button id="nextBtn"> Next </button>
       </div>
       <div>
            <button id="prevBtn"> Previous </button>
       </div>
     );
  }

Here is where I populate the tracks array

    gettingTracks(){
    // store the current promise in case we need to abort it
    if (prev !== null) {
        prev.abort();
    }
    // store the current promise in case we need to abort it
    prev = spotifyApi.searchTracks('genre: pop year:' + this.state.year, {limit: 20, offset:1});
    prev.then((data) => {
        this.setState({
          all_tracks: { 
              tracks: data.tracks.items
            }
        })
        prev = null;
    }, function(err) {
        console.error(err);
    });
}

1 Answer 1

1

You can store the index of the current track as a state variable. And instead of iterating over the tracks to display them, you can just simply display the current track.

Here is a simple example,

import React from "react";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      all_tracks: {
        tracks: []
      },
      currentTrack: 0
    };

    this.onClickNext = this.onClickNext.bind(this);
    this.onClickPrev = this.onClickPrev.bind(this);
  }

  componentDidMount() {
      // fetch the data  from the Spotify API and update this.state.all_tracks.tracks

  }

  onClickNext() {
    //Next button
    this.setState(prevState => {
      if (this.state.currentTrack === this.state.all_tracks.tracks.length - 1) {
        return;
      }

      return {
        ...prevState,
        currentTrack: prevState.currentTrack + 1
      };
    });
  }
  onClickPrev() {
    //Previous button
    this.setState(prevState => {
      if (this.state.currentTrack === 0) {
        return;
      }

      return { ...prevState, currentTrack: prevState.currentTrack - 1 };
    });
  }
  render() {
    const {
      currentTrack,
      all_tracks: { tracks }
    } = this.state;

    // before rendering tracks[currentTrack].name check if tracks[currentTrack] exist

    return (
      <>
        <div>
          <h3>Current Track</h3>
          <h4>
           {
             tracks[currentTrack] 
                ? tracks[currentTrack].name 
                : 'track does not exist'
           }
          </h4>
        </div>
        <div>
          <button id="nextBtn" onClick={this.onClickNext}>
            Next
          </button>
        </div>
        <div>
          <button id="prevBtn" onClick={this.onClickPrev}>
            Previous
          </button>
        </div>
      </>
    );
  }
}

Check the codesandbox for demo

Sign up to request clarification or add additional context in comments.

19 Comments

updated sandbox solution codesandbox
I will create a sandbox with an optimal solution, but without looking at what you are trying in the code it is hard to say why you are getting the error.
codesandbox, there you go updated sandbox example with the repeated queue.
If I have to guess why the warning shouldn't setState inside a setState is happening, probably because you are trying to change the currentTrack conditionally using setState inside of another setState.
|

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.