I have the below object that I am retrieving from the AsyncStorage, and I want to display it in a FlatList
but I am getting the following error:
Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN
My JSON format is:
Object {
"44": Object {
"pro_id": "44",
"pro_img": "url",
"pro_name": " S4 ",
},
"52": Object {
"pro_id": "52",
"pro_img": "url",
"pro_name": " S4 ",
},
}
The JSON above is retrieved from AsyncStorage
like so:
retrieveData = async () => {
try {
await AsyncStorage.getItem('userFavorites')
.then(req => JSON.parse(req))
.then(json => this.setState({ favPro:json }))
} catch (error) {
}
}
My method for rendering items in the FlatList
is defined like this:
fav = ({ item }) => {
return (
<View>
<Text>{item.pro_id+ item.pro_name}</Text>
</View>
)
}
Finally, I render the FlatList
as follows:
<FlatList
data={this.state.favPro}
renderItem={this.fav}
keyExtractor={item => item.pro_id}
/>
How I can display my JSON data using the FlatList
ponent?
I have the below object that I am retrieving from the AsyncStorage, and I want to display it in a FlatList
but I am getting the following error:
Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN
My JSON format is:
Object {
"44": Object {
"pro_id": "44",
"pro_img": "url",
"pro_name": " S4 ",
},
"52": Object {
"pro_id": "52",
"pro_img": "url",
"pro_name": " S4 ",
},
}
The JSON above is retrieved from AsyncStorage
like so:
retrieveData = async () => {
try {
await AsyncStorage.getItem('userFavorites')
.then(req => JSON.parse(req))
.then(json => this.setState({ favPro:json }))
} catch (error) {
}
}
My method for rendering items in the FlatList
is defined like this:
fav = ({ item }) => {
return (
<View>
<Text>{item.pro_id+ item.pro_name}</Text>
</View>
)
}
Finally, I render the FlatList
as follows:
<FlatList
data={this.state.favPro}
renderItem={this.fav}
keyExtractor={item => item.pro_id}
/>
How I can display my JSON data using the FlatList
ponent?
- Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN – othman safadi Commented Oct 16, 2018 at 19:38
2 Answers
Reset to default 5The FlatList
ponent expects an array input for the data
prop. Based on your JSON format, it appears you're passing in an object rather than an array.
Consider the following adjustment to your render method:
// Convert object to array based on it's values. If favPro not
// valid (ie during network request, default to an empty array)
const data = this.state.favPro ? Object.values(this.state.favPro) : []
<FlatList
data={data}
renderItem={this.fav}
keyExtractor={item => item.pro_id}
/>
You're using async / await
incorrectly. Instead of calling .then
you assign your call to await
to a variable (or don't assign it if it does not return a value) and wrap the call (or calls) to await
in a try / catch
block. The await keyword will automatically handle resolve
and reject
so you get the appropriate information.
retrieveData = async () => {
try {
const data = JSON.parse(await AsyncStorage.getItem("userFavorites"))
this.setState({ favPro: data })
} catch (error) {
console.error(error)
this.setState({ favPro: [] })
}
}
You also need to pass an array, the shape of your data looks like an object, but it should be an array of objects. This is not a terribly difficult transformation and I can provide a helper function if you need it.
edit: if you need to convert an object into an array, you can use the reduce
function
const data = {
'44': { a: 2 },
'55': { b: 3 },
}
const dataArr = Object.keys(data).reduce(
(arr, key) => arr.concat(data[key]),
[]
)
By using Object.keys
we can each object by name. Then call reduce
and the array returned by Object.keys
, passing a function as the first argument, and an empty array as the second argument. The second argument is automatically passed to the function as the first argument, arr
, and the second argument of the function we pass is the key of the object. Then it's just a matter of adding the objects to the array using concat
.
Array.reduce
can seem a little overwhelming at first but it's a very powerful method and you can get a lot done with it.