0

I am using fetch method to make API calls on the server. First, I do a request to have an array of objects ( [{"id": 1, "name": "a", "userid": "12"},{"id": 2, "name": "b", "userid": "22"},{"id": 3, "name": "c", "userid": "23"}].

After I need one value of this object to give more information ( in this case I need to userid to have the information of the user).

For that, I am doing multiple requests to show all at the moment. But doing multiple requests is giving me an error.

Objects are not valid as a React child (found: object with keys {_45, _81, _65, _54}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of View

And this is my code. The second fetch is in renderImage function. I put as async but I know that probably is wrong.

class Dashboard extends Component{

    constructor(props){
    super(props)
    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2
      }),
      loaded: false,
       datos: '',
    }

    }

    componentDidMount(){
    this.fetchData();
    }

    fetchData(){
        const REQUEST_URL = "XXXXXXX";
        fetch(REQUEST_URL)
        .then((response) => response.json()) //la convertimos a json
        .then ((responseData) =>{
            this.setState({
                dataSource: this.state.dataSource.cloneWithRows(responseData),
            })          
        })
    }

    renderLoadingView(){
        return(
            <View>
            <Text>Cargando...</Text>
            </View>
            )
    }

    async renderImage(userid){
             const REQUEST_URL = "XXXXXXX" + userid;
             const response = await fetch(REQUEST_URL);
             const json = await response.json();
             this.setState({loaded: true})  
             return (<Thumbnail source={{uri: json.imageUrl}} />)

    }

    renderReceta(receta){
    return(       
                    <Card>
                        <CardItem>
                            <TouchableOpacity onPress={()=> this.onUser(receta)}>
                                 {this.renderImage(receta.user_id)}
                            </TouchableOpacity>
                            <Body>
                                <Text>{receta.Titulo}</Text>
                                <Text>{receta.Username}</Text>
                            </Body>
                          </CardItem>
                   </Card>             
        )   
    }

    render(){

        if(!this.state.loaded){
            return this.renderLoadingView();
        }
        else{
            return(
            <Container>
                <Header><Title>H</Title></Header>
                <ListView 
                dataSource={this.state.dataSource}
                renderRow={this.renderReceta.bind(this)}
                />
            </Container>
                )
        }

    }

}
4
  • can you make a minimal repo so it's easier to understand what you are trying to do? Also, the question is not detailed enough so I understand your case. Commented Oct 25, 2017 at 16:44
  • Yes, first I am doing a fetch to receive some data, after with that data I am doing a second fetch request to show an Image. The first fetch is working okay but in the second is not giving nothing. Commented Oct 25, 2017 at 16:52
  • Objects are not valid as a React child means you are directly trying to render an object, which you cannot do. Check all of your rendered items. I get the sneaking suspicion that it's in renderReceta Commented Oct 25, 2017 at 17:19
  • @Andrew Yes, I trying but I don't see the error. Maybe it was because we call the function multiple times, i mean for every "receta" in renderReceta Commented Oct 25, 2017 at 18:01

1 Answer 1

1

So, one possible solution is to have a different state for the image. For example:

this.state = {
      [...]
      imageLoaded: false
}


  fetchData(){
        const REQUEST_URL = "XXXXXXX";
        fetch(REQUEST_URL)
        .then((response) => response.json()) //la convertimos a json
        .then ((responseData) =>{
            this.setState({
                dataSource: this.state.dataSource.cloneWithRows(responseData),
            })   
            this.renderImage(); //Now you start loading the Image       
        })
    }


renderImage(userid){
             const REQUEST_URL = "XXXXXXX" + userid;
             const response = await fetch(REQUEST_URL);  //You can change this await and just load the fetch in background, does not matter right now. 
             const json = await response.json();
             this.setState({imageLoaded: true, imageUrl: json.imageUrl})  
    }


 renderReceta(receta){
let image = null;
     if (this.state.imageLoaded)
         image = (<Thumbnail source={{uri: this.state.image.imageUrl}} />);
    return(       
                    <Card>
                        <CardItem>
                            <TouchableOpacity onPress={()=> this.onUser(receta)}>
                                 {image}
                            </TouchableOpacity>
                            <Body>
                                <Text>{receta.Titulo}</Text>
                                <Text>{receta.Username}</Text>
                            </Body>
                          </CardItem>
                   </Card>             
        )   
    }

This code won't work right away as I have typos and I stripped things but hopefully you would get the point.

PS. I think I answered a similar question before, please consider accepting your answers so they don't keep un resolved.

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

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.