2

I'm learning Angular but having troubles to understand a point. I want to get data from my server. I used this code (from angular's doc) :

this.myFunction = new function()
{
    var uri = this.getServerUri() + "Connexion/"+login+"/"+CryptoJS.MD5(pass);

            var promises = $http.get(uri)
            .success(function(data, status, headers, config) {
                // this callback will be called asynchronously
                // when the response is available
                //alert("success:"+JSON.stringify(data));
                return data;
            }).
            error(function(data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                return "";
            });
            return promises;
};

But I don't understand the behavior of the success function. When I call this function, it works fine, I get the server's answer but I get the full promises object (I have to write "promises.data" to get my data). Could you explain me why ? Because in the success function I tried to return only the data.

EDIT : I forgot to add my calling function :

var serverAccepted = this.MyFunction().then(function(promise) {
                        var objet = promise.data;
                        if(!_.isEmpty(objet))
                        {
                            userService.setUser(objet, true);
                            return "";
                        }
                        else return "Error while trying to login on the server";

                    });
        return serverAccepted;

Thank you

user2088807
  • 1,378
  • 2
  • 25
  • 47

3 Answers3

4

A promise is a way of dealing with asynchronous requests without blocking. Instead of waiting for a slow operation (like waiting for the server to respond), before executing any more code, a promise is returned and code execution continues.

As such, when you call myFunction in your code above, it will return a promise object.

The promise then provides some neat methods for registering a callback to run code when the server does respond. These methods are .then() and catch() for the success and error case respectively.

Passing a function as an argument will call that function when the server has responded, and you can do with the data what you like. Take this example:

console.log("About to send request");
myFunction()
.then( function (myData){
  console.log("Response received", myData);
})
.catch( function (myError){
  console.error("Oh dear", myError);
});
console.log("Request sent!");

This will log the following to the console:

About to send request
Request sent!
Response received, {}

EDIT

In response to your comment:

why does the response received contains the full promise object and not only the data? Because I return the data in the success function.

The response you receive does not contain a promise at all, but your function returns a promise. In your example serverAccepted is assigned the return value of myFunction() which is a promise and will not change.

The line:

.success(function(data, status, headers, config) {
   return data;
})

Doesn't really do anything at all - returning a value from a .then() or .success() function is only useful if you are going to chain several calls to .then() together - it provides a way of manipulating values without an ever increasing pyramid of nested callbacks. Returning a value from within a promise callback (function passed to .then() or .success()) will not change the promise itself (serverAccepted in your case).

For example:

assume http GET some/url on your server returns:

{
  foo: 'bar',
  dorks: 12
}

When we use $http.get This data is inside the response object as a field called data. Most of the time we don't care much about the rest of the stuff, if the call was successful, we just want the data, so we can return it from the first .then() call (normally inside your service) so that any subsequent .then() calls (e.g. inside a controller) can access the data object directly.

myPromise = $http.get('some/url')
.then( function (response) {
  console.log(response); //--> { status: 200, data: { foo:....}}
  return response.data;
})
.then( function (data) {
  console.log(data); //--> {foo: 'bar', dorks: 12}
  return dorks;
})
.then( function (data) {
  console.log(data); //--> 12
})

console.log(myPromise); //--> promise object with .then() .catch() etc
// ^ THIS WILL NOT CHANGE.
Community
  • 1
  • 1
Ed_
  • 18,798
  • 8
  • 45
  • 71
  • I get this, but why does the response received contains the full promise object and not only the data ? Because I return the data in the success function. – user2088807 Dec 03 '14 at 13:07
2

When I call this function, it works fine, I get the server's answer but I get the full promises object

Sounds like you are doing something like this:

var data = service.myFunction();

Above would be fine in synchronous world, however in case of asynchronous operations this is not correct usage of the promises. Instead you should use returned promise then/success methods:

service.myFunction().then(function(data) {
    console.log(data);
});
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • with `then` and `success` is there a need to inject `$q` and setup a defered/resolve on the response? – user2936314 Dec 03 '14 at 12:44
  • No, `$http.get()` already returns a Promise. All you need to do is to chain `then/success` method, provide a callback and it will be invoked once the promise is resolved. – dfsq Dec 03 '14 at 12:45
  • I pasted my calling function, as you can see I need to write 'promise.data' to make my code work. – user2088807 Dec 03 '14 at 12:52
0

$http request ,returns a promise with two $http specific methods: success and error. success function waits until request is to be finish with success (that means after $http promise resolves), and error function will execute only after the $http promise is rejected.

Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92