Search code examples
angularjsangularjs-1.6

Angular 1.6 Data not displaying when retrieved from service


I am trying to learn the new component syntax. If I set a user variable in the controller statically it works, I see the data on the page. If I try to get the same data from a service, the data is not displayed. I see the data in the then promise after I have assigned it to the this.user variable.

I created a plunkr to show you what I am trying.

http://plnkr.co/BGXesnKBmQGUlVH33jNa

angular.module('myWebApp', ['myModule']);

angular.module('myModule', []);

angular.
    module('myModule').
    component('myComponent', {
        controller: ['myService', function myController(mySvc) {
            mySvc.getUser().then(function (data) { // This gets data but does not populate view. Why?!
                this.user = {
                    name: 'Joe',
                    last: 'Shmoe'
                };

                console.log(user); // Populated with data from service
            });

            // Comment out above and uncoment this and it works!
            // this.user = {
            //     name: 'Joe',
            //     last: 'Shmoe'
            // };

        }],
        template: 'Hello, {{ $ctrl.user.name }}!',
    });

angular.
    module('myModule').
    factory('myService', ['$timeout', function ($timeout) {
        function getUser() {
            // Simulate http get
            return $timeout(function() {
                return {
                    name: 'Joe',
                    last: 'Shmoe'
                };
            }, 1000);
        }

        return {
            getUser: getUser
        };
    }]);

Solution

  • As llp pointed out, this.user is pointing to the function's this, so what you need to do is define this in a variable outside of the function and inside the controller like so (plunker):

    angular.module('myWebApp', ['myModule']);
    
    angular.module('myModule', []);
    
    angular.
        module('myModule').
        component('myComponent', {
            controller: ['myService', function myController(mySvc) {
              var me = this;
                mySvc.getUser().then(function (data) { // This gets data but does not populate view. Why?!
                    me.user = {
                        name: 'Joe',
                        last: 'Shmoe'
                    };
    
                    console.log(me.user); // Populated with data from service
                });
    
                // Comment out above and uncoment this and it works!
                // this.user = {
                //     name: 'Joe',
                //     last: 'Shmoe'
                // };
    
            }],
            template: 'Hello, {{ $ctrl.user.name }}!',
        });
    
    angular.
        module('myModule').
        factory('myService', ['$timeout', function ($timeout) {
            function getUser() {
                // Simulate http get
                return $timeout(function() {
                    return {
                        name: 'Joe',
                        last: 'Shmoe'
                    };
                }, 1000);
            }
    
            return {
                getUser: getUser
            };
        }]);