Joe Smith
Joe Smith

Reputation: 59

JavaScript Promise Not Awaiting Asynchronous Call

I'm working with JavaScript promises, but somewhat new to them and having some issues. In the code below "todoService.addTodo(description);" is an asynchronous call to a server. However, the code does not wait for "todoService.addTodo(description);" to finish, and instead continues executing the code, which means "test" is always equal to null. I'm using promises because I thought this would help deal with the asynch calls, do I'm I simply not understanding the concept, or just doing something wrong syntactically?

let promise = new Promise(function (resolve, reject){
  let test = todoService.addTodo(description);
  console.log(test)

  if (test) {
     console.log("GOOD");
     resolve("OK");
  } else {
      console.log("BAD");
      reject("Unable to connect to server");
  }
});

promise.then(function(result) {
       console.log(result);
    }, function(err) {
        alert(err);
    });

Here is the implementation of addTodo():

addTodo: function (description) {
        serv.todoUrl ='http://localhost:8080/add?description=' + description;
        serv.todoResource = $resource(serv.todoUrl);
        serv.todoResource.save().$promise.then(function (data) {
            console.log(data);
            let toReturn = {result: data.result, details: data.details};
            console.log(toReturn);
            return toReturn;
        }, function (error) {
            return null;
        });

Upvotes: 1

Views: 52

Answers (1)

trincot
trincot

Reputation: 351228

If test is a promise, then if (test) is not the right way to deal with it. What's more, you should not create a new Promise when addTodo already provides the promise.

All you would need is this:

todoService.addTodo(description).then(function(result) {
    console.log(result);
}, function(err) {
    alert(err);
});

Now that you also added the implementation of addToDo in your question, it turns out that it lacks a return of the promise you create there, so it just returned undefined, which obviously is not a promise. Add return here:

addTodo: function (description) {
    serv.todoUrl ='http://localhost:8080/add?description=' + description;
    serv.todoResource = $resource(serv.todoUrl);
    return serv.todoResource.save().$promise.then(function (data) {
//  ^^^^^
        console.log(data);
        let toReturn = {result: data.result, details: data.details};
        console.log(toReturn);
        return toReturn;
    }, function (error) {
        return null;
    });

Note that the other return statements are in the relative callback functions which execute asynchronously, so they don't provide the return value for addToDo, but they provide the resolving value for the promise.

NB: Since you treat the rejection case in addToDo and don't cascade the error, but just return null, addToDo will not represent a rejected promise in that case, but a fulfilled one. If you prefer to have the caller of addToDo to get a rejected promise in that case, then just remove the rejection handler function from within addToDo.

Upvotes: 4

Related Questions