0

So I quite new to this. I want to load a external json file into react, and then use it.

The problem apparently is that the json hasn't been yet loaded, so I get errors. Like Cannot read property 'map' of undefined etc. The console.log give:

1
3
Uncaught TypeError: Cannot read property 'map' of undefined

So I've read this has to do with asynchronous things. But I can't find any example on how to fix it. Or how to make it work.

I would really appreciate it to see a small example like this, to make it work.

Later on I want to make it possible to filter the json with <input type=text etc> with some kind of dynamic search. But first things first. So can someone help me out?

This is my simple file:

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

class App extends Component {

  constructor(){
    super();
    this.state = {
      data: []
    };
    console.log('1');
  };

  componentDidMount() {
    fetch("http://asite.com/file.json")
    .then( (response) => {
      return response.json() })
    .then( (json) => {
      this.setState({data: json});
      console.log('2');
    })
  };

  render() {
    console.log("3");
    return(
      <div className="Employee">
      {
        this.state.data.employees.map(function(employee) {
          return (
            <div>
            <h1> {employee.name} </h1>
            </div>
          )
        })
      }
      </div>
    )
  }
}

export default App;

2 Answers 2

1

Since you have this.state.data.employees, I would assume you want to shape the initial state like this:

constructor(){
  super();
  this.state = {
    data: {
      employees: []
    }
  };
};
Sign up to request clarification or add additional context in comments.

Comments

1

You can either choose to save to the state another variable which is flipped when you know you've loaded the data, or just check to ensure the data exists before trying to map it.

The latter could be done like below:

 <div className="Employee">
  { this.state.data.employees &&
    this.state.data.employees.map(function(employee) {
      return (
        <div>
        <h1> {employee.name} </h1>
        </div>
      )
    })
  }
  </div>

Or you could adjust the initial state to include an empty (but initialized) version of the return such as:

this.state = {
  data: { employees: [] }
};

Checking to ensure the state contains the data field you're mapping is much safer though incase the return ever doesn't include the field.

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.