bfanger / angular-activerecord

A model layer for AngularJS inspired by Backbone.Model
MIT License
137 stars 28 forks source link

Meta Data #21

Open AlexCppns opened 9 years ago

AlexCppns commented 9 years ago

Hello there,

This module looks good! What would be the best approach to include meta data in an index though? For example, if the backend has the following json format for an index call:

{
  comments: [{ id: 1, text: "foo" }, {id: 2, text: "bar"}],
  pagination: { perPage: 5, page: 2, totalCount: 7 }
}
bfanger commented 9 years ago

I'd create a fetchPaged method loosely based on on ActiveRecord.fetchAll() in my base class:

var BaseRecord = ActiveRecord.extend({
}, {
  fetchPaged: function (options) {
     // Return a promise that returns a object with both the results and the meta data.
     // ...
  }
} );

var Comment = BaseRecord.extend({
   $urlRoot: '/api/comments'
});

Comment.fetchPaged({page: 2}).then(function (result) {
  $scope.comments = result.items;
  $scope.total = result.totalCount;
});
AlexCppns commented 9 years ago

Alright this is my solution for a model called Creative:

angular.module('PlatformUi').factory('Creative', ['ActiveRecord', '$q', function (ActiveRecord, $q) {

  return ActiveRecord.extend({

    $urlRoot: '/api/v1/creatives',
    $constructor: function Creative(properties) {
      this.$initialize.apply(this, arguments)
    }
  },{
    modelName: 'creative',
    fetchPaged: function(params){
      var self = this;
      var model = new self();
      var d = $q.defer();
      model.$sync('read', model, self.mergeOptions(params)).then(function (response) {
        var data = response.data;
        if (self.checkPagedData(data)) {
          d.resolve(self.formatPagedData(data));
        } else {
          d.reject('Not a valid response, expecting an array');
        }
      }, d.reject);
      return d.promise;
    },
    checkPagedData: function(data){
      if(angular.isArray(data[this.modelName + 's']) && data.meta != undefined){
        return data.meta.pagination != undefined;
      } else {
        return false; 
      }
    },
    formatPagedData: function(data){
      var result = {};
      result[this.modelName + 's'] = data[this.modelName + 's'];
      result['pagination'] =  data['meta']['pagination'];
      return result;
    },
    mergeOptions: function(params){
      return { headers: { 'Accept': 'application/json' }, params: params };
    }
  });
}]);

Now I just need to find a way to refactor so that I can apply that to any model.