Express + React Problem

Express + React Problem
0

#1

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?


#2

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


#4

@joshuaboulton When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make easier to read.

See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.

Note: Backticks are not single quotes.


#5

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!


#6

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


#7

If you try the following, can you show us what gets displayed to the console?

this.setState({
  ideas: res.claims
}, () => console.log(this.state.ideas));

Not sure which version of React you are using, but you might want to use componentDidMount instead of componentWillMount.


#8

What @RandellDawson said.
componentWillMount is being deprecated.


#9

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:


#10

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


#11

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.