I am having trouble accessing nested objects within arrays within objects

Sheep Snow

I am quite new, this is my first question post I was hoping someone else will of had a similar problem.

API url

I am receiving api data and turning into the JSON format. From that I can access the keys & values within an object (each monster)

hit_points: 17   (key: value)
hit_dice: "5d6"   (key: value)
speed: {fly: 40, walk: 20}   (object)

special_abilities: Array(1)
  0:
   desc: "some text"
   name: "One with Wind"

I am able to access special_abilities[0].name, in this case i get back "One with Wind".

What I cannot work out how to do is when I get more then one ability how to display all 3 without crashing the script when a monster has only 1 ability.

import React, {useState, useEffect} from 'react';
import './App.css';

function currentMonster({match}) {
    const [item, setItem] = useState([]);
    useEffect (() => {
        fetchMonster();
    }, []);

const fetchMonster  = async () => {
    const mob = match.params.id.toLowerCase();
    const fetchMonster = await fetch(`https://api.open5e.com/monsters/${mob}/?format=json`)
    const monster = await fetchMonster.json();
    setItem(monster)
    console.log(monster);
// const abilities = monster.special_abilities[0].name
}
    return (
            <div>
                <h1>{item.name}</h1>
                <p>Size: {item.size}</p>
                <p>Race: {item.type}</p>
                <p>Alignment: {item.alignment}</p>
                <p>Armor Class: {item.armor_class}</p>
                <p>Hit points: {item.hit_points}</p>
                <p>Hit dice: {item.hit_dice}</p>
                <p>Strength: {item.strength}</p>
                <p>Dexterity: {item.dexterity}</p>
                <p>Constitution: {item.constitution}</p>
                <p>Intelligence: {item.intelligence}</p>
                <p>Wisdom: {item.wisdom}</p>
                <p>Charisma: {item.charisma}</p>
                <p>Senses: {item.senses}</p>
                <p>CR: {item.challenge_rating}</p>
            </div>
        )
    }


  export default currentMonster;

This is the code I have currently, I wish to add another <p></p> on the list displaying each special ability and desc of the monsters, and when they have more then one ability those also.

Before asking I have tried to:

const [ability, setAbility] = useState([]);
setAbility(monster.special_abilities[0])
and then <p>{ability.name}</p>

while this works for one monster, if the monster has more then one ability I cannot see them. If the monster has less then two abilities and I log say [0][1][2] the website crashes.

I hope someone can help me with this while questions similar to this have been asked before in stack overflow I have not been able to find inspiration or an answer.

Kind regards,

Sheep

HMR

Here is an example of how to fetch monster when current changes, you can get current from match.params.id but I don't want to make a routed example to demonstrate. Note that I am using monster.slug, this may not be the same as monster name. You should use monster.slug as well because that's what the api uses.

Make sure that current is a dependency of your effect so it'll re run when it changes. I don't think you have your development environment set up correctly because the code you are showing has missing dependencies and your editor should have warned you

const { useState, useEffect } = React;

const App = () => {
  const [current, setCurrent] = useState('aatxe');
  //you can do:
  //const current = match.params.id.toLowerCase();
  const [item, setItem] = useState(null);
  useEffect(() => {
    //SO code snippet doesn't have recent babel, so no
    // async await support in snippet code, changed to
    // promise
    const fetchMonster = () =>
      fetch(
        `https://api.open5e.com/monsters/${current}/?format=json`
      )
        .then(response => response.json())
        .then(setItem);
    fetchMonster();
  }, [current]);

  return (
    <div>
      <select
        value={current}
        onChange={e => setCurrent(e.target.value)}
      >
        <option value="aatxe">Aatxe</option>
        <option value="aboleth">Aboleth</option>
      </select>
      {item && (
        <div>
          <h1>{item.name}</h1>
          <ul>
            {item.special_abilities.map(
              (ability, index) => (
                <li key={index}>{ability.name}</li>
              )
            )}
          </ul>
        </div>
      )}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Accessing nested JSON objects and arrays within objects to display in HTML - AngularJS

Accessing nested objects within objects in PHP not working

Flatten array of objects having arrays nested within their properties

Trouble accessing javascript objects within array

Getting access to deep nested arrays within objects

I am having trouble iterating through an array of objects

Accessing properties of Objects within <#list>

Accessing keys and value of objects within objects

How to access a specific property within a nested but fixed structure of arrays and objects

Modify arrays within objects in jq

Deserialize objects nested within an array

Destroying objects nested within an array

Nested objects within Form in Angular?

How can I work with arrays and json objects within the laravel framework?

How can I unset a value within a nested array of objects? MongoDB

How can I render data within nested objects in react?

JavaScript Objects - I'm having issues accessing an array of objects properties nested multiple levels & combining them together

Aggregating lists within objects having the same key

Accessing data in nested arrays & objects with Go

Having trouble accessing the properties of the objects in my array in Javascript

How to Filter objects and arrays within Javascript Array

getting specific values from objects within arrays

Using 'this' within nested Prototype sub-objects

MongoDB Panache Updating nested objects within Document

Scrapy run for loop within nested json objects

Loop through array of objects, and combine arrays within objects

How to create a JavaScript function to lookup objects and arrays nested within each other

Group objects within nested arrays into array of sub-totals by common property

Loop through objects within objects to create nested menu?