0

I'm trying to map through a list that is stored in the state and pass each item in the list as a prop to another component. Here is what it looks like. The video component is supposed to receive each item from the playlist, title, and description lists then render each video, appropriate title and description until the playlist is over. It seems like the code is rendering the video component but nothing actually shows up.

This is the component that fetches the data and calls the video component.

export class YoutubeFetch extends Component {
  constructor(props) {
    super(props)

    this.state = {
      playlist: [],
      title: [],
      description: [],
      thumbnails: [],
    };
  }

  componentDidMount() {
    return fetch(url)
      .then((response) => response.json())
      .then((responseJson) => {
        // console.log('responseJson', responseJson)
        const playlist = responseJson.items.map(obj => "https://www.youtube.com/embed/" + obj.snippet.resourceId.videoId);
        this.setState({ playlist });
        const description = responseJson.items.map(obj => obj.snippet.description);
        this.setState({ description });
        const thumbnails = responseJson.items.map(obj => obj.snippet.thumbnails.default.url);
        this.setState({ thumbnails });
        const title = responseJson.items.map(obj => obj.snippet.title);
        this.setState({ title });
      })
      .catch((error) => {
        console.log(error)
      })
  }

  render() {
    return (
      <Container>
        <Row>
          {this.state.playlist.map((index) =>
            <Video
              key={index}
              video={this.state.playlist[index]}
              title={this.state.title[index]}
              description={this.state.description[index]}
            />
          )}
        </Row>
      </Container>
    )
  }
}

This is the video component. In the video component, I added a test h1 to see whats happening. The test h1 renders with gaps in between where it seems like the video and etc are supposed to render.

function Video(props) {
  return (
    <Container>
      <Row>
        <h1>test</h1>
        <ReactPlayer
          controls
          url={props.video}
          // height="75%"
          playing={false}
          width="100%"
        />
      </Row>
      <Row>
        <h1>{props.title}</h1>
        <p>{props.description}</p>
      </Row>
    </Container>
  )
}

export default Video

2 Answers 2

0

first of all, do not use class components now.

the issue is here

video={this.state.playlist[index]}

this index is not number based value it is the value present in the array of playlist

to access the number use the second parameter in the map

 {this.state.playlist.map((value,index) =>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! This solved my problem.. Missed the second parameter. Curious why I shouldn't use class components? Is it outdated?
yes, it is outdated. if you look at new react docs all examples are based on functional components. beta.reactjs.org
0

You can do this this way too . create a render function that stores all your components in one array and then return it

const renderMyList = () =>{
mylist = [];
for(let i = 0; i<this.state.playlist.length;i++){
mylist.append(<Video
              key={i}
              video={this.state.playlist[i]}
              title={this.state.title[i]}
              description={this.state.description[i]}
            />) 
}
return mylist;
}

and finally, call this render function

render() {
    return (
      <Container>
        <Row>
          {renderMyList()}
        </Row>
      </Container>
    )
  }
}

1 Comment

good approach , clean code

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.