2

I have a JSON returned object from a file ./jsonData.json.

Inside this file, I have this data:

Note: This is the whole JSON data loaded from the file.

import QuizData from './quizData.json'

This is a new app, so QuizData is all of the following:

[
    {
        "id": 1,
        "name": "Lesson 1",
        "topics": [
            {
                "topicID": 1,
                "topicName": "Science",
                "topicDescription": "Science quiz questions"
            },
            {
                "topicID": 2,
                "topicName": "General Knowledge",
                "topicDescription": "General Knowledge Quiz Questions"
            }
        ]
    }
]

I am trying to get the topic name for each one found and put it out as a Text.

Here is my code:

<FlatList
    data={QuizData}
    renderItem={({ item, index }) =>
        <View>
            <Text>{item.topics.topicName}</Text>
        </View>
    }
    keyExtractor={(item) => item.topicID.toString()}
/>

I have also tried:

{item.topics.[index].topicName}

and

{item.topics[index][topicName]}

But I get the error:

undefined is not an object.

I then thought perhaps its needs to be:

data={QuizData.topics}

and then change the renderItem to:

{item.topicName}

This time there is no error, but there is also no output of text to the screen.

JamesG
  • 1,552
  • 8
  • 39
  • 86
  • Looks like the json data is an array. Is QuizData one element of the json response? – moficodes Apr 16 '20 at 03:52
  • `QuizData` is the whole json file. and that JSON shown is the whole of the json. Its a new app - im just starting out. At the top of this component I have `import QuizData from './quizData.json'` – JamesG Apr 16 '20 at 03:54
  • so what you have is an array of an array. do you want to show all the options in a single entry in the flatlist? – moficodes Apr 16 '20 at 03:55
  • I only want to show `topicName` and `topicDescription`. – JamesG Apr 16 '20 at 03:57

2 Answers2

7

You could do something like this

import * as React from 'react';
import { Text, View, FlatList } from 'react-native';

import data from './data.json';

export default function App() {
  return (
    <FlatList
      data={data}
      renderItem={({ item, index }) => (
        <View>
          {item.topics.map((v, i) => (
            <>
              <Text>{v.topicName}</Text>
              <Text>{v.topicDescription}</Text>
            </>
          ))}
        </View>
      )}
    />
  );
}

Where data.json is a json file in the root directory with your data.

moficodes
  • 781
  • 1
  • 6
  • 21
  • 1
    https://snack.expo.io/@moficodes/433f06 you could try this out here. – moficodes Apr 16 '20 at 04:02
  • Perfect, This works. Will accept when I can. May I ask you some questions: What are the blank tags for you have surrounding texts? Will this cause potential memory issues if lets say this ended up being 5-6 levels down and I have to keep mapping it like so? if yes, any suggestions for improvement? I also get the warning "each child chould have its own key" how would add that? – JamesG Apr 16 '20 at 04:09
  • 2
    because in react / react native everything has to be under one parent tag. usually you will see a lot of empty `` tag. The empty tag lets us enclose two returns with an empty tag but nothing is rendered. Its called the Fragment. you can learn more here https://reactjs.org/docs/fragments.html – moficodes Apr 16 '20 at 04:13
  • 1
    I would first see what is the data source. There could be some pre flattening of the data. Totally depends on what you are trying to render. From the example what it looks like the data is of a list of lessons and each lesson has some topic. If you want to render each lesson as a flatlist item the above will work fine. If you want to render each topic as a flatlist item maybe it will need some reordering either at the data level or at react native lever. Map of map of map might be too complicated to make sense of down the line, also if the data is big and changing will create some issues – moficodes Apr 16 '20 at 04:16
  • Thank you for your time explaining those. – JamesG Apr 16 '20 at 04:28
0

You need to have two maps:

YOUR_OBJECT.map(item => Object.keys(item.topics).map(index => (
   return console.log(item.topics[index].topicName)
   )
));

Mossen
  • 574
  • 5
  • 17