Chao Fang Chao Fang - 5 months ago 12
Javascript Question

Call hprose.httpclient asynchronously in AngularJS

I have a Hprose server which handles user authentication. I am trying to write a logonService which returns a UserInfo object after user logged in. In the code below, hprose.HttpClient.login() is called asynchronously and it takes seconds, but the code in controller keeps going after creating the logonService instance. so that $scope.user is always null, and logonService.logon() is never called. I tried to use $http.get, but cannot figure out how to get a Promise obj using Hprose, instead of Http as in the sample code. A search in Google does not come up with anything useful. Anyone has idea what to do? Thanks.

var app = angular.module("myApp",[])
.service("logonService", function() {
var httpclient = new hprose.HttpClient("http://testurl.com:4800/webapi/", ["login"]);
httpclient.login("userid", "ppt", function(sid) {
console.log("sid1="+sid);
}
this.logon = function() {
console.log("here I am");
return something;
}
})
.controller("myCtrl", ["logonService", function(logonService) {
var user = logonService.logon();
$scope.user = user;
}
)

Answer

Part of problem is the code in myCtrl does not wait for asychronous result of logonService.logon(). Also, we don't know if httpclient.login() returns promises or what. So we need to wrap that in $q promise.

var app = angular.module("myApp",[])

app.service("logonService", function() {
    var loginURL = "http://testurl.com:4800/webapi/";
    var httpclient = new hprose.HttpClient(loginUrl, ["login"]);

    // wrap login fn w/ new $q promise
    this.logon = function(userid, ppt) {
        return $q(function(resolve,reject){ 
            httpclient.login(userid, ppt, function(sid) {
                console.log("sid1="+sid);
                // resolve or reject fn based on results passed to callback
                if (sid) {
                resolve(sid);
                } else {
                reject('sid wasn\'t defined!');
                }
            })
        }
    }

})

app.controller("myCtrl", ["logonService", 
    function(logonService) {
        logonService.logon(userid, ppt).then(function(user){
            //  assign user to scope only after promise resolved
            //  'user' arg will be whatever passed to 'resolve' above
            $scope.user = user; 
        })
        .catch(function(e){
            console.log('An Error happened: ' + e)
            // logon server was down, etc.
        })
    }
])

Here is the good reference for AngularJS' $q. That will let you know how to create Promise in any situation.

Hope this helps you out.

Comments