Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to Manipulate Data Gotten via AJAX Service? Link fn or Controller?

I have a HTML partial that I'm trying to bind AJAX data too. For some reason, it seems I must put the AJAX service call within the directive's link function. I cannot just put it in the controller; I do it in the directive like this:

link: function(scope){
  MyService.getData().then(function(res){
    scope.myData = res.data;
  }, function(res){
    throw new Error('Error getting data');
  });
}

First of all, I'm curious why I cannot do this in my controller. But also, There is some manipulation I want to do to the data once I get it. Does that all need to happen in the linked function. In the controller looping over $scope.myData won't work because it isn't defined yet? Can I use my AJAX data in my controller somehow without having to do my logic in a linked file?

like image 208
1252748 Avatar asked Mar 12 '23 21:03

1252748


1 Answers

The task can be done in various ways but the question is that which practice is the best. First of all if you have a directive with partial and you want to bind to it, you can do it in the directive's controller

app.directive('myPartial', function() {
  return {
    restrict:'AE',
    template:'<pre>[{{myData| json}}]</pre>',
    scope:true,   
    link:function(scope, elem, attrs) {
      /*avoid using model manipulation in link function as it is mostly used 

      for DOM manipulation such as angular.element(elem).addClass('myTemplateClass');*/
    },
    controller: function($scope,MyService){
         MyService.getData().then(function(dataFromServer){
             scope.myData = dataFromServer;
         }, function(err){
            throw new Error('Error getting data : ' + err);
         });
    }
  };
});

You have to have THIN controllers and THICK services when working with AngularJS.. if you have to manipulate data. Do it in the service and return such form of data to controller which is directly assignable to the controller. That's the best practice. I.e. in your service. Do this

app.factory('MyService',function($http,$q){

     var _modifyGetData = function(serverData){
        // modify your data here...
        // for example -> serverData.usersCount = serverData.users.length;
        return serverData;
     };
     var getData = function(){
         var dfd = $q.defer();
         $http.get(/*Some url here*/).then(function(res){
              var data = res.data;
              // manipulate all your data using a function maybe
              data = _modifyGetData(data);
              dfd.resolve(data);   //resolve the modified data


         });
         return dfd.promise;
     }
     return {
        getData:getData
     };
});

Hope this helps.

Some of the online sources that might help: https://scotch.io/tutorials/making-skinny-angularjs-controllers https://teamgaslight.com/blog/4-lessons-learned-doing-angular-on-rails

like image 112
Muhammad Ahsan Ayaz Avatar answered Apr 25 '23 16:04

Muhammad Ahsan Ayaz