Angular.JS API with factory

I wrote a backend service that is used by the Angular.JS frontend using a factory like:

angular.module('app.social', ['ngResource'])
    .factory('Social', function($http) {
        return {
            me: function() {
                return $http.get('http://localhost:3000/me');
            },
            likeVideo: function(link) {
                return $http.post('http://localhost:3000/like/video', { link : link });
            },
            post: function(link) {
                return $http.post('http://localhost:3000/post', { link : link });
            },
            postVideo: function(link) {
                return $http.post('http://localhost:3000/post/video', { link : link });
            },
            friends: function() {
                return $http.get('http://localhost:3000/friends');
            },
            taggableFriends: function() {
                return $http.get('http://localhost:3000/friends/taggable');
            },
            videos: function() {
                return $http.get('http://localhost:3000/videos');
            }
        };
    });

      

The Social.me endpoint gets profile information from the REST backend. However, this feature is used in various Angular controllers (profile page, detail page page, title account button, etc.). This means that for each view, profile information is requested from http: // localhost: 3000 / me . Is this good practice or is it better to cache information in a factory?


EDIT: Updated code (based on answer from @Rebornix):

angular.module('app.social', ['ngResource'])
    .service('SocialService', function() {
        var serviceData = {
            me: null
        };
        return serviceData;
    })
    .factory('Social', function($http, SocialService) {
        return {
            me: function() {
                if (SocialService.me === null) {
                    return $http.get('http://localhost:3000/me').then(function(response) {
                        SocialService.me = response.data;
                        return SocialService.me;
                    });
                } else {
                    return SocialService.me;
                }
            }
        }
    };
});

      

In the controller, I use:

angular.module('app.profile', [])
    .controller('ProfileCtrl', ['$window', '$scope', 'Social', function($window, $scope, Social) {
        $scope.me = Social.me();
    }])

      

And the view:

<div ng-controller="ProfileCtrl">
    <h1 class="profile-name">{{ me.name }}</h1>
</div>

      

But the view is not refreshed as the Facebook.me value gets initialized on the first request. I am assuming that I need to manually start $ scope. $ Apply () somehow?

+3


source to share


2 answers


You can create a service as a store for controllers like

angular.module('app.social', ['ngResource'])
.service("SocialService", function() {
   var info = {
     me: null,
     friends: []
   };
   return info;
})
.factory('Social', function($http, SocialService) {
    return {
        me: function() {
               $http.get('http://localhost:3000/me').then(function(response){
               SocialService.me = response.data;
               });
        },

      

Then, in all your controllers, a link infoService

instead of calling the API again. What you need to get the latest data and update infoService

, with this change the entire controller area will be notified.

In your controller



angular.module('app.profile', [])
    .controller('ProfileCtrl', ['$window', '$scope', 'SocialService', 'Social', function($window, $scope, SocialService, Social) {
    $scope.SocialService = SocialService;
    // Kick off social factory to update user info, you can move it into 
    // any other functions like `ng-click`.
    Social.me();
}])

      

Then in your opinion

{{SocialService.me}}

      

+4


source


(function (app) {
'use strict';

app.factory('myService', MyService);

MyService.$inject = ['$q', 'serviceResource'];

function MyService($q, serviceResource) {
    var jobs = [];

    var service = {
        getJobs: getJobs
    };

    return service;

    //////////////////////////////////////

    function getJobs(refresh) {
        if (refresh) {
            return serviceResource.autosysJobs().$promise.then(function (data) {
                    jobs = data;
                    return jobs;
                }, function (err) {
                    throw err;
                });
        }
        else {
            var deferrer = $q.defer();
            deferrer.resolve(jobs);
            return deferrer.promise;
        }
    }
}
}(angular.module('app')));

      

you can pass the bool argument to tell the weather to get a local copy or a new copy



It all depends on how often the data changes when the back end data changes and the degree of tolerance for data inconsistencies in your application. if the original data changes too much and you can't afford incompatible data, then you have no choice but to get a new copy every time, but if it doesn't, you can get the data locally.

0


source







All Articles