1

I'm setting up a basic WebApp here using ReactJS. Right now I can add data to my database using POST request no problem, the thing, my backend response sends me a JSON with all the data that I passed and the _id in the database. I need to get this _id and save it in my state so I can pass it along to the next URL in my WebApp. That's the code for my POST request :

  SubmitClick(){

    if (this.state.password !== this.state.reTypepassword){
      alert('Passwords do not match. Please check your data !');
    } else {
      //console.log(this.state); //debug only
      fetch('http://localhost:4000/users/', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          //'Authorization': 'Basic YWRtaW46c3VwZXJzZWNyZXQ=',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          email: this.state.email,
          first_name: this.state.first_name,
          last_name: this.state.last_name,
          personal_phone: this.state.personal_phone,
          password: this.state.password
        })
      })
      .then(response => response.json())
      .then(parsedJSON => console.log(parsedJSON._id))
      .catch(error => alert('Check your data', error))
      .then(this.props.history.push('/get')) // change page layout and URL
    }
    console.log(this.state.id); //debug to see if the _id is saved in my state
  }

Here is my constructor:

  constructor(props){
    super(props);
    this.state={
      email:'',
      first_name:'',
      last_name:'',
      personal_phone:'',
      password:'',
      reTypepassword:'',
      id:''
    }
  }

I tried calling a function after parsedJSON that used this.setState(), using function(parsedJSON){this.state.id : parsedJSON._id}. I tried with a new function like this:

  changeID(parsedJSON){
    this.setState({id : parsedJSON._id})
  }

and changing the .then(parsedJSON => console.log(parsedJSON._id)) to .then(parsedJSON => this.cahngeID(parsedJSON)). But none of then worked...

I left the code with .then(parsedJSON => console.log(parsedJSON._id)) so can make sure that I can see this value, and in my console it`s printed perfectly.

Here is a example of the response send by my backend: {"email":"testing@gmail.com","first_name":"TESTER","last_name":"Testing","personal_phone":"(55) 2020-5252","password":"12345","_id":"5a27f511cd7d7a0db8ab65b9"}

How can I get the "_id" from my response?

rk_Tinelli
  • 79
  • 2
  • 3
  • 10
  • What was the syntax for your original this.setState() call? Also, I think you'll want to move your debug to see if the _id was saved to the state inside your then(), where it's at currently will not give you the correct result. – Rnice4christ Dec 06 '17 at 13:59
  • changeID(parsedJSON){ this.setState({id : parsedJSON._id}) } – rk_Tinelli Dec 06 '17 at 14:01

2 Answers2

1

You should not touch the this.state property directly. React will throw an error if you do this because React needs to know when this.state has been updated so that it can keep track of the changes. It cannot do this if you manipulate the property directly. That's why we have React.Component#setState. The "shallow" version is the most commonly used, where you pass an object that will be merged into your state. For example, the following:

.then(parsedJSON => this.setState({ id: parsedJSON._id }))

is equivalent to:

Object.assign(this.state, { id: parsedJSON._id });

except that React gets to keep track of when the state is updated.

Note that setState is also asynchronous and takes a callback as the second parameter. You can read more about that here.

As per the comment below, this other Stack Overflow question was helpful to the OP (Why calling react setState method doesn't mutate the state immediately?)

Sara M
  • 455
  • 3
  • 7
  • So instead of using `.then(parsedJSON => this.setState({ id: parsedJSON._id }))` I have to use `Object.assign(this.state, { id: parsedJSON._id });` ? I got the following error : `Line 40: 'parsedJSON' is not defined no-undef`. If i use `.then(parsedJSON => Object.assign(this.state,{ id: parsedJSON._id }))` nothing changes actually. – rk_Tinelli Dec 06 '17 at 14:36
  • 1
    hey Alex, using the information that you offered I searched in the internet how to immediately change my state before moving on with the code, an then the callback function in the setState shows up. I found this question here that helped me to fix my problem, together with your info: [Question](https://stackoverflow.com/questions/30782948/why-calling-react-setstate-method-doesnt-mutate-the-state-immediately) Thanks for the help ! – rk_Tinelli Dec 06 '17 at 15:13
0

At the end of your constructor add this line of code:

this.SubmitClick = this.SubmitClick.bind(this);

because JavaScript does not bind the instance value of 'this' to our methods.

Danilo Carrabino
  • 397
  • 6
  • 12
  • I added this to my constructor, and tried the codes that I mentioned in the question, but nothing really changed... Do I have to make more changes in the code? – rk_Tinelli Dec 06 '17 at 14:42