Riza Mk
Riza Mk

Reputation: 63

undefined is not an object react-native

I am having a problem with setting a state to data from fetch API response

render() {
    function getCode(text) {
      fetch('url', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          "telephone": text, 
          "password": "123123"
        })
      }).then(response => response.json())
      .then(response => {
        console.log(this.state.text)
        console.log(this.state.uid)

        this.setState({uid : response["data"]["telephone"]})
        console.log(this.state.uid)
      // this.setState({uid: response["data"]["telephone"]})
      // console.log(this.state.uid); 
    })
  }

here is my constructor

constructor(props) {
   super(props);
   this.state = {
      text: '',
      uid: ''
   }
}

So I am just sending a request, and need to save response inside of the state, but instead, I am getting an error:

TypeError: undefined is not an object (evaluating '_this2.state.text')]

Code lines which is commented are my attempts to fix it.

UPD 1: here is response from APi

{"data":{"telephone":["Some data"]}}

Upvotes: 2

Views: 1962

Answers (2)

nem035
nem035

Reputation: 35501

The issues is that you are creating a function within a method and this within a function doesn't refer to the this in your method.

render() {
  function getCode(text) {
    // `this` in here is not the React component
  }
}

Here's a simple example:

class Example {
  method() {
    // `this` within a method (invoked via `.`) points to the class instance
    console.log(`method=${this}`);
   
    function functionInAMethod() {
      // because functionInAMethod is just a regular function and
      // the body of an ES6 class is in strict-mode by default
      // `this` will be undefined
      console.log(`functionInAMethod=${this}`);
    }
    
    functionInAMethod();
  }
}

new Example().method();

You can just extract getCode as another class method and call this.getCode() when needed.

getCode() {
  // ...
}

render() {
  this.getCode();
}

Other options are to:

  1. bind the this of getCode when creating the function
  2. use call or [apply][3] to set the this when invoking the function
  3. use an arrow function for getCode to preserve the this across nested functions
  4. bind the this into a variable in render and use that variable within getCode instead of this

⚠ Note: You don't want to make http requests in the render method because it is called quite frequently, consider doing it in a less brittle manner. The usual pattern is to do it in the constructor or componentDidMount.

Upvotes: 1

Bonjov
Bonjov

Reputation: 305

you declare that function when component did mount inside render function

 class Something extends React.Component {
  constructor(props) {
      super(props);
      this.state = {
        text: '',
        uid: ''
      }
  }

   getCode = (text) => {
      fetch('url', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          "telephone": text, 
          "password": "123123"
        })
      }).then(response => response.json())
      .then(response => {
        console.log(this.state.text)
        console.log(this.state.uid)

        this.setState({uid : response.data.telephone})
        console.log(this.state.uid)
      // this.setState({uid: response["data"]["telephone"]})
      // console.log(this.state.uid); 
      })
  }

  render() {
    return(
      //...you can call it this.getCode(/..../)
    )
  }

}

Upvotes: 1

Related Questions