jose.padilla
jose.padilla

Reputation: 39

React: How do I fix getting undefined when passing api data to child component using axios?

I'm having problems accessing data that I pass it to a child component. This may have to do with the Promise not being resolved at the time of accessing it but that's what I don't know how to fix. What I need is to make sure the data is fully retrieved from the parent and then passed to the child component ApplicationStats.

This is the code I wrote for the parent component:

import axios from 'axios';
import ApplicationStats from './ApplicationStats';

const Apps = () => {
  const [apiData, setApiData] = useState([]);
  const ifaUrl= 'url1';
  const orgUrl = 'url2';

  const fetchData = () => {
    const ifaResponse = axios.get(ifaUrl);
    const orgResponse = axios.get(orgUrl);
    axios.all([ifaReq, orgReq]).then(
      axios.spread((...responses) => {
        setApiData({
          ifaResult: responses[0];
          orgResult: responses[1];
        });
      }),
    );
  };

  useEffect(() => {
    fetchData();
  }, [])

  return (
    <div className="card-deck"
      <ApplicationStats apiData={apiData} />
    </div>
  );
};

This is the child component:

import React from 'react';

const ApplicationStats = ({apiData}) => {
  const {ifaResult, orgResult} = apiData;
  console.log(ifaResult.data);

  return (
    <div>Hey</div>
  );
};

In the child component, if I replace console.log(ifaResult.data) with console.log(ifaResult), I get this undefined and then I get the data.

undefined

What I'm trying to do is to keep my console.log(ifaResult.data) in the child component, but I get this

error

I've even tried using async/await, but I feel I'm missing something important.

Upvotes: 1

Views: 1506

Answers (2)

Brandon
Brandon

Reputation: 122

The issue is that you're initializing apiData as an array, rather than an object. Here's the issue, demonstrated:

let x = [];
const { property } = x; // property === undefined!
console.log(property.data) // ERROR! Cannot find property `data` of undefined

The reason this breaks is because when Javascript checks an object for a property that doesn't exist, it returns undefined. However, when you check for a property off of undefined, JavaScript will throw an error.

This will prevent you from getting the error, and will log undefined to the console instead of breaking:

const [apiData, setApiData] = useState({ ifaResult: {}, orgResult: {}});

Another Contrived Example:

const x = undefined;
x.data // ERROR!

//...

const x = {}
x.data // undefined

Upvotes: 1

Quentin
Quentin

Reputation: 943615

Your initial value for apiData is an empty array.

When the Ajax response arrives you replace it with an object that has a ifaResult property.

… but by then you’ve already rendered the component using the initial data and got the error.

———

When you set the initial data for the state, make it the same shape as the data you intend to put in it later.

Upvotes: 1

Related Questions