fahmijaafar
fahmijaafar

Reputation: 185

How to fetch complex json into React Native Flatlist?

I'm trying to fetch an API from a news API however the format is a little hard for me to extract the data from. I have tried to parse the json into an array but still wasn't able to fetch the data into a flatlist. May I have any suggestion to overcome this problem? thanks for any help. I've built this on expo which can be tested on the following link. The following is the API class:

import React, {Component} from 'react';
import {Text, ActivityIndicator, FlatList} from 'react-native';

export default class API extends Component{

  constructor(props){
    super(props);
    this.state = {
      isLoading: true,
      data: null
    }
  }
  
  componentDidMount(){
    fetch('https://newsapi.org/v2/top-headlines?country=my&category=sports&apiKey=73e8cdd9f6be475cb4a2d128bae3650c')
    .then((response) => response.json())
    .then((responseJson) => {
      //tried to simplify the json(I'm not sure whether its right)
      //var parsedjson = JSON.parse(responseJson);
      //var myarray = parsedjson.articles;
      this.setState({
        isLoading: false,
        data: responseJson//myarray,
      })
    })
    .catch((error) => {
      console.error(error);
    });
  }

  _renderItem = ({item, index}) =>{
    return(
        //I think here's the problem. I've tried to use {item.articles.title}
        <Text>{item.title}</Text>
    )
  }

  render(){
    if(this.state.isLoading){
      return(
            <ActivityIndicator style={{marginTop: 250}} size="large" color='white'/>
      )
    }else{

      let {data, isLoading} = this.state;
      return(
          <FlatList
          data={data}
          renderItem={this._renderItem}
          keyExtractor={(item,index)=> index.toString()}
          />
    )
    }
  }
}

Using the same way, I managed to fetch API which has a format like

[
   {
       "id": "1",
       "title": "GG",
       "body": "the body here",
       "image": "image link",
       "link": null
   }]

but now its not working when using json with format like this:

{
  "status": "ok",
  "totalResults": 38,
  "articles": [
     {
       "source": {
         "id": "the-washington-post",
         "name": "The Washington Post"
       },
       "author": "Rachel Lerman, Cat Zakrzewski, Heather Kelly",
       "title": "Apple"
     }
  ]
}

Upvotes: 1

Views: 382

Answers (2)

Hamid khan
Hamid khan

Reputation: 57

what you want to fetch from the given json, if u have multiple date in json then you have to pass positions. you have to write like this import jsonObject from 'path' then if u want to get articles array then write jsonObject.articles etc

Upvotes: 0

nithinpp
nithinpp

Reputation: 2025

In your componentDidMount, you have

componentDidMount(){
    fetch('https://newsapi.org/v2/top-headlines?country=my&category=sports&apiKey=73e8cdd9f6be475cb4a2d128bae3650c')
    .then((response) => response.json())
    .then((responseJson) => {

      //var parsedjson = JSON.parse(responseJson); 
      // you don't need to parse the json here. It's already a JSON object.
      this.setState({
        isLoading: false,
        data: responseJson, // here you can do either responseJson or responseJson.articles.
      })

    })
    .catch((error) => {
      console.error(error);
    });
  }

You don't need to use JSON.parse() on a JSON. You can read more about JSON parse at MDN

Now, in your FlatList, you have,

<FlatList
  data={data}
  renderItem={this._renderItem}
  keyExtractor={(item,index)=> index.toString()}
/>

In your data prop of Flatlist, change the data to either data.articles or just data depending on the state you have set to your data.

If you have used,

this.setState({
  isLoading: false,
  data: responseJson,
})

You will have to make the data prop of FlatList like below,

<FlatList
  data={data.articles}
  renderItem={this._renderItem}
  keyExtractor={(item,index)=> index.toString()}
/>

Or if you have set the data state as,

this.setState({
  isLoading: false,
  data: responseJson.articles,
})

you can simply keep the FlatList as it is now.

Now on your _renderItem,

_renderItem = ({item, index}) =>{
    return(
        <Text>{item.title}</Text>
    )
  }

This is how it should be. You don't need to use {item.articles.title}, as you have already supplied the articles array to your FlatList component.

Upvotes: 1

Related Questions