0

I want to implement a login function using AngularJS and my backend is in Rails. i decided to implement it using the $httpBackend but I have a problem.

When it gets into the $httpBackend function, it does update the token with the latest token from the database but i need to return the value to my services of which that doesnt seem to be happening. I know this has to do with promise and deferred etc but i am not well conversant with those.

SO this is my code

  var authorized = false;
    var token;

    $httpBackend.whenPOST('https://login').respond(function(method, url, data) {
            var loginDetails = data;
            var d= $q.defer();

            function startToken(loginDetails) {
          getTokens.newToken(loginDetails).then(function(result) {
            if(result.length > 0) {
              var updateDB = "UPDATE preferences SET value='"+result[0].token+"' WHERE description='token'";
              $cordovaSQLite.execute(db, updateDB).then(function(res) {
                var updateDB1 = "UPDATE preferences SET value='true' WHERE description='logged_in'";
                $cordovaSQLite.execute(db, updateDB1).then(function(res) {
                  var query = "SELECT description, value FROM preferences";
                  $cordovaSQLite.execute(db, query).then(function(res) {
                    if(res.rows.length > 0) {
                      if(res.rows.item(3).value!=null || res.rows.item(3).value!='') {
                        getTokens.getCRMToken(res.rows.item(2).value).then(function(resulttoken){
                          if(resulttoken[0].token == res.rows.item(3).value) {
                            token = res.rows.item(3).value;
                          }
                        d.resolve(token)
                        });  
                      } 
                    } else {
                      console.log("No results found");
                    }
                  }, function (err) {
                      console.error(err);
                  }); 
                }, function (err) {
                  console.error(err);
                });

              }, function (err) {
                console.error(err);
              });  
            }
            else {
              console.log("reject")
              d.reject(result);
            }   
          }, 1000);
          return d.promise;
        }

        var a = startToken(loginDetails).then(function(token) {
    // in here the value for token is correct i then go ahead to set the value for authorized and resolve it           
          console.log(token)
              if(token.length > 0){
                console.log("authorized true")
                authorized = true;
                d.resolve(token, authorized)

              }
              else
              {
                console.log("authorized false")
                authorized = false;
                d.reject(token, authorized)
              }
              return d.promise;
        })

// this is where i have my issue. all i want to do is to just check if the value for authorized is true, if yes, return the value for token. 
                //authorized = true;
                //return  [200 , { authorizationToken: token }];
        });
Kingsley Simon
  • 2,090
  • 5
  • 38
  • 84
  • Seems you need to learn how promises work. You basically say, "declare var tokens, do something later(), return tokens (declared but undefined)". Without knowing what you are returning into it's hard to advise how you should use the promise. You could return the token as an object which gets populated by the promise later, or you could just return the promise object. Either way, you need to write more code to handle a non-blocking function call. – doog abides May 18 '15 at 17:49
  • thanks @doogabides could you point me in the right direction? – Kingsley Simon May 18 '15 at 17:55

1 Answers1

2

Complete rewrite

Sadly, I think the short answer is that you cannot use promises with $httpBackend. See this discussion: https://github.com/angular/angular.js/issues/11245

In my original answer, I didn't recognize that you were using the $httpBackend mock as I merely concentrated on your incorrect promise code. The information on promises (https://docs.angularjs.org/api/ng/service/$q) is still valid.

The unit test version of ngMock does not handle promises. If you are using a version of $httpBackend which can handle promises, you need to return the promise, not the [200, "status"].

However, that said, in your rewrite, you also reuse the same promise after it has been resolved which is incorrect. You can only resolve or reject a defer once. So you need to either chain your then() functions or create a new defer. Also, you didn't actually need to create a defer since the newToken() function actually returns a promise.

doog abides
  • 2,270
  • 16
  • 13