SilentDev
SilentDev

Reputation: 22747

AngularJS binding two variables together without being told to do so

This is my Controller (home.js):

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

        var self = this;

        self.posts = BaseService.posts;

        BaseService.fetch.postsY(function() {
            self.posts = BaseService.posts;
        });

        self.like = function(id, postType) {
            BaseService.like(id, postType, function() {
                console.log(self.posts);
            });
        };
    }]);

This is BaseService (base.js):

angular.module("BaseApp", [])
    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var self = this;
        self.posts = {};
        self.cerrorMessages = [];

        self.fetch = {
             postsY: function(callback) {
                 $http.get('/postsY/')
                 .then(function(response) {
                     self.posts = response.data;
                     callback();
                 }, function(response) {
                     // Do something with the error.
                 });
             }
         };

        self.like = function(id, postType, callback) {
            $http.post("/" + postType + "/" + id + "/like/")
            .then(function(response) {
                angular.forEach(self.posts, function(post, index, obj) {
                    if (post.id == id) {
                        post.usersVoted.push('voted');
                        post.voted=true;
                    };
                callback();
                });
            }, function(response) {
                 // Do something with the error.
            });
        };

        return self;
    }]);

When I load home.html (which loads home.js), the posts are loaded successfully (because in the callback for BaseService.fetch.postsY() I do self.posts = BaseService.posts after fetching and changing BaseService.posts. The weird thing is, after I like a post (which calls self.like), self.posts gets updated on home.html automatically, even without me doing self.posts = BaseService.posts in the callback for self.like (when I log self.posts on home.html in the callback for self.like, I can see that post.voted=true). Why does AngularJS automatically update self.posts in home.html without me doing self.posts = BaseService.posts in the callback for self.like?

According to the answer by @AntonioLaguna in this post: AngularJS updates variable in a different file without being instructed to do so

it is becuase I am binding self.posts to BaseService.posts when I do BaseService.fetch.postsY(), however, if I change BaseService.fetch.postsY() to this:

        BaseService.fetch.postsY(function() {
            // Do nothing in the callback.
        });

then self.posts on my controller remains empty even after fetching the posts (even though I binded self.posts on my controller in the line before by doing:

self.posts = BaseService.posts;

With that said, how come calling self.like() automatically updates self.posts on my controller even though calling BaseService.fetch.postsY() with an empty callback function does not (considering that I already binded self.posts to BaseService.posts at the beginning of my controller)?

Upvotes: 0

Views: 40

Answers (1)

Claies
Claies

Reputation: 22323

In the case of BaseService.posts, you are first assigning it to an empty object and then assigning it to an entirely different object (response.data), which is presumably an array, in the postsY function. The controller will still have a reference to the empty object, and have no idea that the object has been replaced by the service with an array.

In the case of self.like(), That function is merely iterating through the existing array of posts and modifying the properties of the objects. If the controller is properly pointing to the array of objects, since the array itself isn't being removed and replaced, the controller will be pointing to the same instance of all the objects in the array in memory, and changes to these object's properties will be reflected.

Upvotes: 1

Related Questions