Shauna
Shauna

Reputation: 181

Correct way to fetch through array

In the below compoenent, the function is neverending. Can someone tell me what to fix so that in the end the beers array in the state has 5 names?

export default class GetBeers extends React.Component {
    constructor() {
        super();
        this.state = {
          beers: [],
          didError: false
        };
      this.getBeerInfo = this.getBeerInfo.bind(this);
    }
    
    render() {
      return (
        ...
    }
    getBeerInfo() {
        let beerArr = [1,2,3,4,5];
        this.props.beerArr.map(id => {
          fetch(`https://api.punkapi.com/v2/beers/${id}`)
          .then(res => res.json())
          .then(json => {
            this.setState(state => {
              const beers = state.beers.concat(json[0].name);
         
              return {
                beers
              };
            });
          })
          .catch(err => {
            this.setState({
              didError : true
            });
          });
        })
      }
}

Upvotes: 0

Views: 76

Answers (3)

AfamO
AfamO

Reputation: 899

You can improve the render method using a combination of ternary operator(to display appropriate message when it cannot reach the server), format with map and ordered list to get something like this :

render() {
    return (
        <div><ol>{this.state.beers.length!==0 ? this.state.beers.map((beer)=><li>{beer}</li>) :"Could not retrieve any bears. Try again/ensure you can access the server/networtk"}</ol></div>
    )
}

Upvotes: 0

Anupam Minz
Anupam Minz

Reputation: 125

Well your code should be somethings like this ..

import React from 'react';
export default class GetBeers extends React.Component {
    constructor() {
        super();
        this.state = {
            beers: [],
            didError: false
        };
        this.getBeerInfo = this.getBeerInfo.bind(this);
    }

    render() {
        return (
            <div>{this.state.beers}</div>
        )
    }
    
    componentDidMount() {
        this.getBeerInfo()
    }

    getBeerInfo() {
        let beerArr = [1,2,3,4,5];
        beerArr.map(id => {
            fetch(`https://api.punkapi.com/v2/beers/${id}`)
                .then(res => res.json())
                .then(json => {
                    this.setState({
                        //const beers = state.beers.concat(json[0].name);
                        //return {
                            //beers
                        //};
                        beers: this.state.beers.concat(json[0].name)
                    });
                    console.log('well at least this works')
                })
                .catch(err => {
                    this.setState({
                        didError : true
                    });
                });
        })
    }
}

It is advised that you use the componentDidMount() lifecycle method for the fetch api and add what @atahnksy said.

Upvotes: 2

atahanksy
atahanksy

Reputation: 102

When you are using setState, you can try this:

this.setState({ beers: [...this.state.beers, json[0].name])

This might fix your problem.

Upvotes: 1

Related Questions