Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to implement a SIMPLE promise in Reactjs

Just trying out Promises for the first time in React. I have a basic promise working (ripped from someone else's code), but don't know how to adapt it to be useful.

What I have so far (within my render() function)

  var promise = new Promise( (resolve, reject) => {

     let name = 'Dave'

     if (name === 'Dave') {
        resolve("Promise resolved successfully");
     }
     else {
        reject(Error("Promise rejected"));
     }
  });

  promise.then(function(result) {
     console.log(result); // "Promise resolved successfully"
  }, err => {
     console.log(err); // Error: "Promise rejected"
  });

Sure enough, as the promise conditional is matched (name === 'Dave'), my console logs Promise resolved successfully.

However, I don't know how to assign a value to a variable when using the promise. For example:

  promise.then(function(result) {
     var newName = 'Bob'
  }, function(err) {
     var newName = 'Anonymous'
  });

And then when I try to return this value in render()'s return statement, like so:

<h2>{newName}</h2>

It says newName is undefined.

I have also tried:

  promise.then(function(result) {
     var newName = result
  }, function(err) {
     var newName = error
  });

...expecting this would assign the resolve or error string into newName variable, but nope.

Am I thinking about this the wrong way? How can I make this more useful than just logging a string when my conditional is met?

Any help would be appreciated, because this is really making my head hurt...


Update

 render() {

      var promise = new Promise( (resolve, reject) => {

         let name = 'Paul'

         if (name === 'Paul') {
            resolve("Promise resolved successfully");
         }
         else {
            reject(Error("Promise rejected"));
         }
      });

      let obj = {newName: ''};

      promise.then( result => {
         obj["newName"] = result
      }, function(error) {
         obj["newName"] = error
      });

      console.log(obj.newName)

    return (
      <div className="App">
         <h1>Hello World</h1>
         <h2>{obj.newName}</h2>
      </div>
    );
  }
like image 686
Paulos3000 Avatar asked Oct 13 '16 19:10

Paulos3000


People also ask

How do you use promises in react JS?

Creating a promise We can create new promises (as the example shows above) using the Promise constructor. It accepts a function that will get run with two parameters: The onSuccess (or resolve ) function to be called on success resolution. The onFail (or reject ) function to be called on failure rejection.

What is a promise in react JS?

When we make a promise in React Native, it will be executed when the execution time comes, or it will be rejected. A promise is used to handle the asynchronous output of an executed operation. With promises, we can execute a code block until a non-block async request is complete.

Which method is used to resolve a promise in react?

resolve() The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise.

How do you get the promise value in react?

To get promise value in React and JavaScript, we can use await . to create the getAnswer function that calls fetch with await to get the response data from the promise returned by fetch . Likewise, we do the same with the json method. And then we call setAns to set the value of ans .


2 Answers

You are using React in a wrong way. A Promise is designed to return result at a later point of time. By the time your promise has been resolved or rejected, your render would have finished execution and it wont update when the promise completes.

render method should only depend on props and/or state to render the desired output. Any change to prop or state would re-render your component.

  • First, identify where your Promise should go in the life cycle of the component(here)
  • In your case i would do the following

    • Initialize an state inside your constructor(ES6) or via getInitialState

      constructor(props) {
        super(props);
        this.state = {
          name: '',
        };
      }
      
    • Then on componentWillMount or componentDidMount which ever suits you, call the promise there

      componentWillMount() {
       var promise = new Promise( (resolve, reject) => {
      
        let name = 'Paul'
      
        if (name === 'Paul') {
         resolve("Promise resolved successfully");
        }
        else {
         reject(Error("Promise rejected"));
        }
       });
      
       let obj = {newName: ''};
      
       promise.then( result => {
        this.setState({name: result});
       }, function(error) {
        this.setState({name: error});
       });
      }
      
    • Then in render method write something similar to this.

      render() {
       return (
        <div className="App">
         <h1>Hello World</h1>
         <h2>{this.state.name}</h2>
        </div>
       );
      }
      
like image 131
Panther Avatar answered Sep 16 '22 20:09

Panther


You need to be thinking about the scope you're in. When you are in the function you're passing to promise.then, you are in a new block scope and therefore any var you create in the function won't exist outside of it's scope. I'm not sure how you're defining your React components, but assuming you have a newName variable on your component, there are two ways you could solve the scope problem - bind and arrow functions:

promise.then(function(result) {
  this.newName = result; //or what you want to assign it to
}.bind(this))

and then you could reference it using {this.newName}

Or with an arrow function:

promise.then((result) => {
  this.newName = result; //or what you want to assign it to
}.bind(this))

I would recommend watching this egghead video to help you understand the this keyword in javascript.

like image 28
Ian Mundy Avatar answered Sep 17 '22 20:09

Ian Mundy