0

I have a nested JSON, the reason I fail to render is arrays in data{} are not initilaized. The same reason in this question: How do I access elements of an array in a property in Javascript object?

Now the situation is much more complex, should I do it in the same way? If so, how do I initialize this nested JSON? Or is there any smarter way?

Following is the API response:

{
    "index": "dwarf",
    "name": "Dwarf",
    "speed": 25,
    "ability_bonuses": [
        {
            "ability_score": {
                "index": "con",
                "name": "CON",
                "url": "/api/ability-scores/con"
            },
            "bonus": 2
        }
    ],
    "alignment": "Most dwarves are lawful, believing firmly in the benefits of a well-ordered society. They tend toward good as well, with a strong sense of fair play and a belief that everyone deserves to share in the benefits of a just order.",
    "age": "Dwarves mature at the same rate as humans, but they're considered young until they reach the age of 50. On average, they live about 350 years.",
    "size": "Medium",
    "size_description": "Dwarves stand between 4 and 5 feet tall and average about 150 pounds. Your size is Medium.",
    "starting_proficiencies": [
        {
            "index": "battleaxes",
            "name": "Battleaxes",
            "url": "/api/proficiencies/battleaxes"
        },
        {
            "index": "handaxes",
            "name": "Handaxes",
            "url": "/api/proficiencies/handaxes"
        },
        {
            "index": "light-hammers",
            "name": "Light hammers",
            "url": "/api/proficiencies/light-hammers"
        },
        {
            "index": "warhammers",
            "name": "Warhammers",
            "url": "/api/proficiencies/warhammers"
        }
    ],
    "starting_proficiency_options": {
        "choose": 1,
        "type": "proficiencies",
        "from": [
            {
                "index": "smiths-tools",
                "name": "Smith's tools",
                "url": "/api/proficiencies/smiths-tools"
            },
            {
                "index": "brewers-supplies",
                "name": "Brewer's supplies",
                "url": "/api/proficiencies/brewers-supplies"
            },
            {
                "index": "masons-tools",
                "name": "Mason's tools",
                "url": "/api/proficiencies/masons-tools"
            }
        ]
    },
    "languages": [
        {
            "index": "common",
            "name": "Common",
            "url": "/api/languages/common"
        },
        {
            "index": "dwarvish",
            "name": "Dwarvish",
            "url": "/api/languages/dwarvish"
        }
    ],
    "language_desc": "You can speak, read, and write Common and Dwarvish. Dwarvish is full of hard consonants and guttural sounds, and those characteristics spill over into whatever other language a dwarf might speak.",
    "traits": [
        {
            "index": "darkvision",
            "name": "Darkvision",
            "url": "/api/traits/darkvision"
        },
        {
            "index": "dwarven-resilience",
            "name": "Dwarven Resilience",
            "url": "/api/traits/dwarven-resilience"
        },
        {
            "index": "stonecunning",
            "name": "Stonecunning",
            "url": "/api/traits/stonecunning"
        },
        {
            "index": "dwarven-combat-training",
            "name": "Dwarven Combat Training",
            "url": "/api/traits/dwarven-combat-training"
        },
        {
            "index": "tool-proficiency",
            "name": "Tool Proficiency",
            "url": "/api/traits/tool-proficiency"
        }
    ],
    "subraces": [
        {
            "index": "hill-dwarf",
            "name": "Hill Dwarf",
            "url": "/api/subraces/hill-dwarf"
        }
    ],
    "url": "/api/races/dwarf"
}

This is my code:

import React, {Component} from 'react'
import { Grid, Header, Label } from 'semantic-ui-react'

class raceWindow extends Component {
    constructor(props)
    {
        super(props)
        this.state = {
            data: {}
        }
    }

    componentDidMount()
    {
        fetch(this.props.hdAPI)
        .then(response=>response.json())
        .then(data => {this.setState({data: data})});
        this.setState({hdAPI: this.props.hdAPI});
    }

    componentDidUpdate(prevProps)
    {
        if(this.props.hdAPI !== prevProps.hdAPI)
        {
            fetch(this.props.hdAPI)
            .then(response=>response.json())
            .then(data => {this.setState({data: data})});
            this.setState({hdAPI: this.props.hdAPI});
        }
    }

    render()
    {
        const { data } = this.state;
        return(
        <div>
            <Header size = 'huge'>{data.name}</Header>
            <Grid container>
            {
                Object.entries(data).slice(2).map(
                    ([attr, value]) => {
                        return(

                        {/*Following code does not work because: 
                            this.state = {data:{}}
                        arrays inside data is not initialized,
                        what should I do to render every element?*/}

                        <Grid.Column>
                            <Label horizontal>{attr}</Label>
                            {value}
                        </Grid.Column>
                        );
                    }
                )
            }
            </Grid>
        </div>
        );
        
    }
}

export default raceWindow
DeepDream
  • 3
  • 2
  • as your code, it will render from the third element. as your data, {value} can be an object, a text or an array. so you have to check type of it to render by type. something like : Array.isArray(value).... – tuan nguyen Jun 22 '21 at 03:49
  • Thanks you, it works! I am wrong at first. This is not the problem of 'data:{}', I just need to check the type. – DeepDream Jun 22 '21 at 04:44

0 Answers0