0

This is my Main Controller:

angular.module("HomePageApp", ["BaseApp"])
    .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) {

        var self = this;

        self.posts = BaseService.fetch['YPosts']();
        self.logoutUser = function() {
            console.log(self.posts);
            BaseService.logout();
        };

    }]);

and this is my BaseService (some return objects are not shown for simplicity sake):

angular.module("BaseApp", [])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }])

    .config(['$locationProvider', function($locationProvider){
        $locationProvider.html5Mode(true);
    }])

    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var cerrorMessages = [];
        var posts = {};
        return {

        fetch: {
            XPosts: function() {
                $http.get('/postsX/')
                .then(function(response) {
                    posts = response.data;
                }, function(response) {
                    posts = {};
                    cerrorMessages = BaseService.accessErrors(response.data);
                });
                return posts;
            },

            YPosts: function() {
                $http.get('/postsY')
                .then(function(response) {
                    posts = response.data;
                    console.log(posts);
                    return posts;
                }, function(response) {
                    console.log('here');
                    posts = {};
                    cerrorMessages = BaseService.accessErrors(response.data);
                });
            }
        }
    };
}]);

When I log posts in my BaseService, it consists of objects. But when I click logout (which logs posts again), it says that it is undefined. Any idea why?

SilentDev
  • 20,997
  • 28
  • 111
  • 214
  • Possible duplicate of [How to return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – lyjackal Nov 19 '15 at 04:28

2 Answers2

1

The then() in your YPosts is a Promise callback, and returning a value there isn't the same as returning a value from YPosts. What you do in XPosts also won't work: you return posts in XPosts itself, but the value will not have been set yet, because in most cases the $http.get won't have called the then/success callback yet.

You could introduce another callback as in lyjackal's answer, or just use the existing one in the right place:

       YPosts: function() {
            return $http.get('/postsY')
       }

and

    var self = this;
    BaseService.fetch.YPosts().then(
        function(response) { self.posts = response.data; },
        function(response) { ... } // error handler
    );

    self.logoutUser = function() {
        console.log(self.posts);
        BaseService.logout();
    };

Beware, though, that if the logoutUser function is called before YPosts is complete, the console.log(self.posts) will again show undefined.

Kenney
  • 9,003
  • 15
  • 21
  • And do I return `posts` or return `self.posts`? In both cases, I am still getting `undefined` on the front-end when I click "logout" :/ – SilentDev Nov 19 '15 at 03:07
  • @Kenny Correction to my above comment, if I return `posts` it gives an error saying `posts is not defined` but when I return `self.posts` then it is still `undefined` when I click the "logout" button. On my front-end, I am also looping over `self.posts` but nothing is showing up (meaning it is empty). – SilentDev Nov 19 '15 at 03:17
  • Ah indeed, I see what you mean. My answer is wrong. I'll change it ;-) Updated! That's it, right? – Kenney Nov 19 '15 at 03:29
  • I have `return posts` right after my `console.log()` function :) – SilentDev Nov 19 '15 at 04:15
  • Meh. :-) (It was late ;-)). But I know the answer now - assuming that your `XPosts` also doesn't work. – Kenney Nov 19 '15 at 13:22
1

a return statement only returns from the scope of its function. Javascript tends to encourage passing callbacks to long running functions so that the code doesn't block other activities. If you want the value of posts once the get request is resolved, have YPosts take a callback:

        YPosts: function(callback) {
            $http.get('/postsY')
            .then(function(response) {
                posts = response.data;
                console.log(posts);
                callback(posts);
            }, function(response) {
                console.log('here');
                posts = {};
                cerrorMessages = BaseService.accessErrors(response.data);
            });
        }

Edit:

Call YPosts like this:

BaseService.fetch.YPosts(function(posts) {
    self.posts = posts;
});
// however note that the callback will not be executed until the request completes
// so `self.posts === undefined` out here
lyjackal
  • 3,984
  • 1
  • 12
  • 25