9

I'm trying to use $http, but why it return null result?

angular.module('myApp')
.factory('sender', function($http) {
    var newData = null;
    $http.get('test.html')
        .success(function(data) {
            newData = data;
            console.log(newData)
        })
        .error(function() {
            newData = 'error';
        });
    console.log(newData)
    return newData
})

Console say: http://screencast.com/t/vBGkl2sThBd4. Why my newData first is null and then is defined? How to do it correctly?

1
  • Hey, if my answer was what you were after please accept it so it doesn't stay open forever. Cheers! Commented Jul 21, 2014 at 22:13

2 Answers 2

20

As YardenST said, $http is asynchronous so you need to make sure that all functions or display logic that are dependent on the data that is returned by your $http.get(), gets handle accordingly. One way to accomplish this is to make use of the "promise" that $http returns:

Plunkr Demo

var myApp = angular.module('myApp', []);

myApp.factory('AvengersService', function ($http) {

    var AvengersService = {
        getCast: function () {
            // $http returns a 'promise'
            return $http.get("avengers.json").then(function (response) {
                return response.data;
            });
        }
    };

    return AvengersService;
});


myApp.controller('AvengersCtrl', function($scope, $http, $log, AvengersService) {
    // Assign service to scope if you'd like to be able call it from your view also
    $scope.avengers = AvengersService;

    // Call the async method and then do stuff with what is returned inside the function
    AvengersService.getCast().then(function (asyncCastData) {
            $scope.avengers.cast = asyncCastData;
    });

    // We can also use $watch to keep an eye out for when $scope.avengers.cast gets populated
    $scope.$watch('avengers.cast', function (cast) {
        // When $scope.avengers.cast has data, then run these functions
        if (angular.isDefined(cast)) {          
            $log.info("$scope.avengers.cast has data");
        }
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

Great answer!! I'm going to add this to my blog!! :)
@sk8terboi87ツ Then click that up vote; it's what it's for! :)
This definitely works, but I can't believe this is the most efficient way of creating a data factory in Angular. Either way, the OP should mark this answer as correct.
5

This JavaScript code is asynchronous.

console.log(newData)
return newData

Is executed before what inside success

newData = data;
console.log(newData)

So at first time, the newData is null (you set it to be null)

And when the http response is returned (inside the success), the newData gets its new value.

This is very common in Javascript, you should do all your work inside the success.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.