skip to Main Content

I should start out by saying I’m pretty new to React.

When a component mounts, I need to fetch an API endpoint, and assign the JSON response to state data. Ultimately, I need to pass the JSON response to another component.

I’ve tried putting the fetch directly in the componentDidMount() function but that did not work. Below, you can see the error generated in the console. This is at line 25 console.log("This data => " + JSON.stringify(this.state.data));

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'data')

Any insight into how I can pass the response of /profile/:id to the ResultsDashboard component would be helpful.

Below is the code I have for my component.

import ReactDOM from 'react-dom';
import {  Tabs } from 'antd';
import { ResultsDashboard } from './ResultsDashboard.js'


export class TestResults extends React.Component {
    constructor(props){
        super (props);
        
    }
    getProfileData (){
        console.log("Making a fetch for URL /profile/" + window.location.href.split('/')[4])
        fetch('/profile/' + window.location.href.split('/')[4]).then( response => {
          console.log("Response in Fetch => " + JSON.stringify(response))
          this.setState({data:  response.json()})
          this.setState({urls: this.getUrls()}); 
        });
    }
    componentDidMount(){
        this.getProfileData();
    }
    getUrls(){
        const urls = [];
        console.log("This data => " + JSON.stringify(this.state.data));
        for (var x = 0; x < this.state.data.length; x++){
            urls.push(this.state.data[x].url)
        }
        return urls
    }
    render (){
        
        return(
            <div>
                <Tabs
                    defaultActiveKey="1"
                    type="card"
                    size="large"
                    items={this?.state?.urls?.map((url,index) => {
                      return {
                          label: `${url.substr(0,75)}`,
                          key: index,
                          children: <ResultsDashboard testIndex={index} aggregateData={this.state.data}/>
                      };
                  })}
                  
                />
            </div>
        );
    }
} 

2

Answers


  1. In fact you are assigning a function to urls.

    You can try using this.setState in the getUrls function assigning urls variable and passing data as argument

    getProfileData (){
        console.log("Making a fetch for URL /profile/" + window.location.href.split('/')[4])
        fetch('/profile/' + window.location.href.split('/')[4]).then( response => {
          console.log("Response in Fetch => " + JSON.stringify(response))
          this.setState({data:  response.json()})
          this.getUrls(response.json()); 
        });
    }
    
    getUrls(data){
        const myVar = [];
        console.log("This data => " + JSON.stringify(data));
        for (var x = 0; x < data.length; x++){
            myVar.push(data[x].url)
        }
        this.setState({urls: myVar})
     }
    
    Login or Signup to reply.
  2. Try this .then((response) => response.json()).then((data) => {...}

    And its better to change this.getUrls() to this.getUrls(data), cause the value of this.state.data might not be update yet.

    getProfileData() {
      console.log("Making a fetch for URL /profile/" + window.location.href.split("/")[4]);
      fetch("/profile/" + window.location.href.split("/")[4])
        .then((response) => response.json())
        .then((data) => {
          console.log("Response in Fetch => " + JSON.stringify(response));
          this.setState({ data: data });
          this.setState({ urls: this.getUrls(data) });
        });
    }
    

    Also, remember to add this.state = { data: {}, urls: [] }; in constructor().

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search