tommyd456
tommyd456

Reputation: 10683

Handling promises in Angularjs

I would like to know how to handle promises properly when there is a condition involved too.

For example I have this code:

if(something == true) {
  loginObj.$login("anonymous").then(function(){ //handling the promise
    //do something with the promise
    //do something line 1
    //do something line 2
    //do something line 3
    //do something line 4
    //do something line 5
  });
}
else {
  //do the same thing line 1
  //do the same thing line 2
  //do the same thing line 3
  //do the same thing line 4
  //do the same thing line 5
}

I hope you can see my problem. If something is true then I will have to wait for the promise to resolve before executing my lines of code. However, my else block contains nearly all the same lines of code but I'm having to repeat myself.

Why can I do to avoid this duplication?

Upvotes: 0

Views: 101

Answers (4)

marneborn
marneborn

Reputation: 699

I like using $q.when()/$q.reject() to create a resolved promise in situations like this.

var promise;
if ( something === true ) {
    promise = loginObj.$login("anonymous")
    .then(
        function(){ //handling the promise
            //do something with the promise
        }
     );
}
else {
    promise = $q.when("somethingelse");
    //promise = $q.reject("somereason");
}
promise.then(
    function (somethingelse) {
        //do something line 1
        //do something line 2
        //do something line 3
        //do something line 4
        //do something line 5
    }
);

Upvotes: 0

mccainz
mccainz

Reputation: 3497

Execute the repeated lines in a 'finally/always' block.

For instance if using $q,

var outputPromise = getInputPromise()
.fin(function () {
    // close files, database connections, stop servers, conclude tests
});

Or if using Jquery...

$.get( "test.php" ).always(function() {
  alert( "$.get completed with success or error callback arguments" );
});

Alternately if your code cannot be structured such that the login alternate methods can flow in a promise chain then you can simply remove both login functions to a single function which returns a promise and then chain that function, as below.

http://plnkr.co/edit/nJRaBb04JpLdHicgxg2u?p=preview

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Hello Plunker!</h1>
    <button id="loginBtn">Login</button>

    <script>

    function login1(){
       var $def =$.Deferred();
       window.setTimeout(function(){
         $def.resolve("loginMethod1");
       },1000);
       return $def.promise();
    }

    function login2(){
       var $def =$.Deferred();
       window.setTimeout(function(){
         $def.resolve("loginMethod2");
       },1000);
       return $def.promise();
    }

    function login(val){
      var $def =$.Deferred();
      if(val){
        login1().then(function(res){
           $def.resolve(res);
        });
      }
      else{
        login2().then(function(res){
           $def.resolve(res);
        });
      }
      return $def.promise();
    }

    $("#loginBtn").bind("click",function(){
        login(Math.random()>0.5)
        .then(function(res){
          console.log(res + " ...do everythign else here");
        });
    });

    </script>
  </body>

</html>

Upvotes: 1

Fordio
Fordio

Reputation: 3820

if(something == true) {
  loginObj.$login("anonymous").then(function(){ //handling the promise
    //do something with the promise
    doSomething();
  }).
  catch(function() { // catch code } ).
  finally(function() { // finally code });
}
else {
  doSomething()
}

function doSomething() {
  //do the same thing line 1
  //do the same thing line 2
  //do the same thing line 3
  //do the same thing line 4
  //do the same thing line 5
}

Upvotes: 1

graphefruit
graphefruit

Reputation: 364

Lay down a function to call?

$scope.doTheSame= function()
{

}

if(something == true) {
  loginObj.$login("anonymous").then(function(){ //handling the promise
    //do something with the promise
    $scope.doTheSame()
  });
}
else {
  $scope.doTheSame()
}

And pass needed parameters, or if you're working with scope objects you can still acess them

Upvotes: 1

Related Questions