0

I can't access the data object properties in the parent component

After I fetch the data from the api in the child function, I receive a json data. Within the .then promise if I console log the response I get [object Object]. If I console log response.page or response.results[1].title I get the expected object property, but log of response.results gives [object Object] [object Object].

Also I need the data in the parent component, so I put that data in fetchedData state hook, and returned it. So inside the parent component if I console log the data from the function. I get as [object Object]. And if I do maindData.data or mainData.data.page, I get an error saying data or page of undefined is not accessible unlike in the previous case where at least I was getting the property.

What could be the cause of this error? Is it because react hooks always returns an Array rather than an object? If so than what could be the solution for this ??


Parent component

import React, {useEffect, useState} from 'react';
import axios from "axios"
import {useParams} from 'react-router-dom'
import TmdbApiUrl from "./apiUrl"
import {FetchUrl} from "./fetchUrl"
import "../assets/mediaList.sass"
import Navigation from "./partials/nav";
import MediaCard from "./partials/mediaCard";


const MediaList = ()=> {
   const {generalType} = useParams();
   const {media} = useParams();
   const {page} = useParams();
   const key=process.env.API_KEY;
   const url=`${TmdbApiUrl.baseURL()}${media}/${generalType}?api_key=${key}&page=${page}`;
   const {mainData,loading,status}=FetchUrl(url);

  console.log(`#loading==>${loading}`);
  console.log(`#FetchedData==>${mainData.data}`);
  console.log(`#status==>${status}`);

  return (
    <div className="mediaList">
      <Navigation />
      <div className="list m-5 d-flex flex-wrap justify-content-around">
        <MediaCard/>
        {/*{data.map(media=>(*/}
        {/*<div className="m-5">*/}
        {/*  <MediaCard*/}
        {/*      rating={true}*/}
        {/*      ratingValue={media.vote_average}*/}
        {/*      year={media.release_date}*/}
        {/*      title={media.title}*/}
        {/*      text={media.overview}/>*/}
        {/*</div>))}*/}
      </div>
    </div>
  );
};
export default MediaList

Child function

import {useEffect, useState} from 'react';
import axios from "axios";

export const FetchUrl=(url)=> {
  const [fetchedData,setFetchedData]=useState({mainData:null,loading:true,status:null});
  console.log(`url==>${url}`);
  useEffect(()=>{
    setFetchedData({mainData:null,loading:true,status:null});
    axios
      .get(url)
      .then(response=>{
        console.log(`response==> ${response}`);
        setFetchedData({mainData:response.data,loading: false,status:response.status});
        })
      .catch((error)=> console.log(`sorry for the ${error}`));
  },[url]);
  return fetchedData;
};

JSON data from TMDB API

{
data:{
  "page": 1,
  "total_results": 10000,
  "total_pages": 500,
  "results": [
    {
      "popularity": 564.69,
      "vote_count": 2822,
      "video": false,
      "poster_path": "/xBHvZcjRiWyobQ9kxBhO6B2dtRI.jpg",
      "id": 419704,
      "adult": false,
      "backdrop_path": "/5BwqwxMEjeFtdknRV792Svo0K1v.jpg",
      "original_language": "en",
      "original_title": "Ad Astra",
      "genre_ids": [
        18,
        878
      ],
      "title": "Ad Astra",
      "vote_average": 5.9,
      "overview": "(description..bla..bla..bla...)",
      "release_date": "2019-09-17"
    },
    {
      "popularity": 194.755,
      "vote_count": 12119,
      "video": false,
      "poster_path": "/5vHssUeVe25bMrof1HyaPyWgaP.jpg",
      "id": 245891,
      "adult": false,
      "backdrop_path": "/lvjRFFyNLdaMWIMYQvoebeO1JlF.jpg",
      "original_language": "en",
      "original_title": "John Wick",
      "genre_ids": [
        28,
        53
      ],
      "title": "John Wick",
      "vote_average": 7.2,
      "overview": "(description..bla..bla..bla...)",
      "release_date": "2014-10-22"
    }
  ]
},
  status:200
}


5
  • yea I'am passing the URL to the child, fetching the data in the child, and returning it to the parent component. Child is just a file with FetchUrl named function in it and importing it in the parent component. Commented Apr 6, 2020 at 20:39
  • It seems that you are confused by [object Object]? This is what is displayed when you try to log an object. If you really want to see what the object contains, you do a console.log(JSON.stringify(obj)). This will convert the object to a JSON string so that you actually can see the contents of the object Commented Apr 6, 2020 at 20:40
  • i think for dinamic fetch would be better to do HOC Commented Apr 6, 2020 at 20:42
  • @ Viktor yea I know that by doing JSON.stringify(obj) I can see the output, that Isn't the issue. I want to access the obj properties using (dot .) like obj.page, obj.data.title Commented Apr 6, 2020 at 20:46
  • @Daviti It would be better in HOC's but I want to reuse this function and imp it from a seperate file. Also want to find the issue here. Commented Apr 6, 2020 at 20:50

3 Answers 3

1

Found a solution but using redux. If the fetched json data was huge i.e. deeply nested say for example

API object=A:{
             B:{ 
               C:{ 
                 D:E }
                 }
               }

then I would have had to put if statements for each of the deeper object keys i.e.

received data=A.B.(C?C:null).(D?D:null)

or else it would give me C or D as undefined and this is not an efficient solution. So then I used mapDispatchToProps & mapStateToProps from redux which dispatched the fetchAPI action and loaded the entire data before putting it into redux state.

Sign up to request clarification or add additional context in comments.

1 Comment

You can also do A?.B?.C?.D
0

You are setting data in wrong way

setFetchedData({data:{mainData:response.data},loading: false,status:response.status});

should be

setFetchedData({ mainData:response.data ,loading: false, status:response.status });

5 Comments

sorry my bad... that is what I was trying to do in the first place. was just messing around to see the corresponding changes in output.
so what's the issue now?
In the child function after using hooks, I return the data from the state. In the parent component I assign the returned data from the function to new object variables. So then if I console log mainData.data I get [object Object] and JSON.stringyfy shows a string of the actual output. But the if I try to access the properties like mainData.data.page or mainData.data.results I get an error saying cannot access page of undefined!
Which means you are accessing it the wrong way. Console log and then play with this to find the right property access path
The path is correct.. I made a new variable and assigned Object.create(mainData.data) to it. Then if I do variable.page or variable.results I get the correct output. But again can't access the further nested objects. Throws similar errors. Hence now I stopped using hooks and converted the parent function to a class with state and componentDidMount method. And it works fine here i.e. I can access the properties with dot notation (this.state.mainData.data.page)! So why does this issue occurs with hooks??
0

Select the position of the object in the array and then access the property. Eg:

User[0].name

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.