I'm new to JSON and filtering. The data.json file and FolderScreen.js below render the following chapter structure in a react native
ListView
. With react-navigation
props are passed down to render the related nested subchapters in the ListView
.
This works flawlessly for Chapter 1
and rendering it's Subchapter A
, B
and C
in the ListView
…
Level 1 > Chapter 1
Subchapter A
Subchapter B
Subchapter C
… but as soon as Subchapter A
is passed down to the FolderScreen.js all its Sub-Subchapters A1
, A2
and A3
are not rendered as expected in the ListView
with the snippet below…
Level 2 > Subchapter A
Sub-Subchapter A1
Sub-Subchapter A2
Sub-Subchapter A3
…am I missing something in the JSON filter?
Or just doing it wrong?
{ "id":"chapter-1", "name":"Chapter 1", "type":"folder", "content":[ { "id":"sub-chapter-a", "name":"Subchapter A", "type":"folder", "content":[ { "id":"sub-sub-chapter-a1", "name":"Sub-Subchapter A1", "type":"file" }, { "id":"sub-sub-chapter-a2", "name":"Sub-Subchapter A2", "type":"file" }, { "id":"sub-sub-chapter-a3", "name":"Sub-Subchapter A3", "type":"file" } ] }, { "id":"sub-chapter-b", "name":"Subchapter B", "type":"file" }, { "id":"sub-chapter-c", "name":"Subchapter C", "type":"file" } ] }
renderRow = () => { const entry = this.props.navigation.getParam('chapterID', ''); const listEntry = jsonData.map(all => all.content.filter(parent => parent.id === entry).map(item => item.content.map(i => { return ( <ListEntry id={i.id} name={i.name} type={i.type} navigation={this.props.navigation} key={i.id} /> ); }) ) ); return listEntry; };
This is an easy one. Your code expects there to always be a content
property which is an array (or an object that has a .map()
method, anyway).
In the innermost level, there is no "content": []
property.
Either add one, or just add a check in for the content
property before you try to use it.
My favorite technique is to use (item.content || []).map(...
, to use an empty array if the property is null or undefined.
Your last map returns an array with only one entry. You need to access the first array item [0] or modify your code to iterate through results.
Here is a simplified version of what works:
const listEntry = jsonData.content
.filter(sub => sub.id === entry)
.map(subsub => subsub.content)[0]
.map(item => {
return <ListEntry id={item.id} name={item.name}/>
}
);
So you should change your code to access the first array member before using the last .map:
const listEntry = jsonData.map(all =>
all.content.filter(parent => parent.id === entry).map(item =>
item.content)[0].map(i => {
return (
<ListEntry
id={i.id}
name={i.name}
type={i.type}
navigation={this.props.navigation}
key={i.id}
/>
);
})
)
);
Here is a working Snack for my sample code: https://snack.expo.io/@navardan/nested-contents
Here is also a good article on .map and .filter Simplify your JavaScript – Use .map(), .reduce(), and .filter()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.