Express + React Problem

I have an Express API that sends a JSON object. This object has a property that is an array of objects. One of the properties in those objects is ‘title’.

How would I use fetch to set the state with this JSON object, and display that title property from the state in a JSX element?

Do you have some code to show us what you’re attempting to do?

1 Like

This is the Argument model:


var argumentSchema = new Schema({
  title: String,
  premises: Array,
  conclusion: String
});

This is the Express API route:


router.get("/", (req, res) => {
  Argument.find({}, (err, result) => {
    if (err) console.log(err);

    res.json({ claims: result });
  });
});

This is the contents of the React component:


constructor(props) {
    super(props);
    this.state = {
      ideas: []
    };
  }

  componentWillMount() {
    fetch("/workbench")
      .then(res => res.json())
      .then(res => {
        this.setState({
          ideas: res.claims
        });

        console.log(this.state.ideas);
      });
  }

  render() {
    return <h1>{this.state.ideas[0].title}</h1>;
  }

In this component, if I change that h1 to some simple text (like “Hello world”) it runs error free - that console.log works, displaying an object as I expect in the console. I don’t understand why I’m unable to access this.state.ideas[0].title, though. :confused: It says it is undefined.

Thanks in advance for any help!

Hey @joshuaboulton,
the Component’s setState method is asynchronous, so the console.log will run before the method returns a result.

1 Like

What @camperextraordinaire said.
componentWillMount is being deprecated.

1 Like

When I switch to componentDidMount and change the console.log to use that callback, I get the same console.log I got before, which is this:

Thanks for the heads up re: componentWillMount, by the way. :slight_smile:

If you have not yet figured it out, try:

        <h1>{ this.state.ideas[0] &&
            this.state.ideas[0].title
          }</h1>

This will conditionally render this.state.ideas[0].title only if this.state.ideas[0] has a value which is not falsy. So as long as this.state.ideas[0] is an object, it’s title will be rendered.

1 Like