0

I'm trying to return just the first fruit/color data from this read-only example JSON:

"start": 0,
"limit": 1,
"filteredSize": null,
"results": [
    {
        "id": 20587193,
        "fruit": "apple",
        "color": "red",
    },
    {
        "id": 20587191,
        "fruit": "banana",
        "color": "yellow",
    }
]

Using a FlatList in React Native:

<FlatList
data={data.results}
keyExtractor={({ id }, index) => id.toString()}
renderItem={({ item }) => (
<exampleComponent
fruitData={item.fruit}
colourData={item.color} />
)}
/>

Here is my API call:

fetch('http://localhost:8080/login', headers)
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, []);

However, the above returns both fruits and colors:

apple, red
banana, yellow

I'm aware I need to access the index of the first element of data.results but I'm not sure where to put this in my code.

If I add in a console.log of data.results as a chained .then as follows:

fetch('http://localhost:8080/login', headers)
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .then(function(){
        console.log("dataResults: " + data.results)
      })
      .finally(() => setLoading(false));
  }, []);

For some reason it calls 3 times, but the first time is undefined, so perhaps this is the reason I am having trouble:

console.log output:

dataResults: undefined
dataResults: [object Object],[object Object]
dataResults: [object Object],[object Object]

Many of my attempts return a TypeError: Cannot read property '0' of undefined error, such as changing the console.log call to be:

console.log("dataResults: " + data.results[0])

Update

I now know that the console.log is being called multiple times because useEffect is being re-rendered, and not that useEffect is being called multiple times itself.

However, I still don't understand why I can't access data.results to filter, but I can access data.results to use it as a whole?

How can I edit the data array before using it in my FlatList?

Phil Penny
  • 113
  • 1
  • 17

2 Answers2

0

It is not possible to use [0] in renderItem. You can use simply use array slice() method to get only fist elements.

Example:

<FlatList
   data={results.slice(0, 1)}
   keyExtractor={item => item.id}
   renderItem={({ item }) => (
     <exampleComponent
        fruitData={item.fruit}
        colourData={item.color} />
      )}
/>
Vicky
  • 157
  • 1
  • 10
  • I don't seem to be able to do that, `data={data.results.slice(0,1)}` returns `TypeError: Cannot read property 'slice' of undefined` – Phil Penny Jun 09 '21 at 13:20
  • You can use this array. var results = [ { "id": 20587193, "fruit": "apple", "color": "red", }, { "id": 20587191, "fruit": "banana", "color": "yellow", } ] – Vicky Jun 09 '21 at 13:47
  • I'm sorry I don't understand; I cannot edit the json data, it is ready only, I can sort it but what I am trying to do is only return one result out of the 2 (or 100) that exist. That may be the first result (index 0), or it may be another position in the array. – Phil Penny Jun 09 '21 at 14:28
0

It turns out, when accessing nested parts of JSON, the data was returning as an object rather than an array, but Flatlist expects an array.

I found this answer on S.O. (https://stackoverflow.com/a/43969184) meaning I simply needed to do the following:

if(data.results != undefined){
      var fruitArray = Object.entries(data.results)
}

I still don't think I am using state correctly, hence the if(data.results != undefined) control, but it is at least working for now.

This means I can now access a single fruit using firstFruitName = fruitArray[0][1]

Phil Penny
  • 113
  • 1
  • 17