1
votes

I'm trying to access metadata using Ember Data, using ActiveModelAdapter. If the controller is set up in the router with model:

App.ClaimsIndexRoute = Ember.Route.extend
  authRedirectable: true
  model: ->
    @store.findAll 'claim'

And the controller as a meta method as follows:

App.ClaimsIndexController = Ember.ArrayController.extend
  meta: (->
    @store.metadataFor('claim')
  ).property()

Then I can access the metadata in the index template:

{{meta.page}} {{meta.per_page}} {{meta.total_pages}}

But I needed to add filtering. So I changed the router to use setupController:

App.ClaimsIndexRoute = Ember.Route.extend
  setupController: (controller, model) ->
    controller.loadClaims()

And in the controller added the loadClaim function:

App.ClaimsIndexController = Ember.ArrayController.extend
  loadClaims: ->
    _filter = @get 'filter'
    _result = @store.find 'claim', {filter: _filter}
    @set 'model', _result
  filter: ''
  meta: (->
    @store.metadataFor('claim')
  ).property()
  actions:
    filterClaims: ->
      @loadClaims()

Now the metadata is no longer available. I've entered the context using a debugger and can't seem to get anything.

Is there a problem with sending a query to Ember Data? Is there a better way to do this?

Incidentally, the metadata is sent by the server as suggested in the docs.

I'm using Ember 1.6.1 and Ember data 1.0.0-beta.8.2a68c63a

1
Is your issue that you say controller.loadClaims() instead of controller.send('loadClaims')? - Josh Padnick
Thanks for the suggestion. Didn't change the behavior. - noel

1 Answers

4
votes

You could try several different ways for getting metadata. I didn't write on coffee, so I'll try to describe solutions using javascript.

  1. Declare meta property of ClaimsIndexController as depended on model.meta property: meta: function() { return this.get('model.meta'); }.property('model.meta')

  2. Declare meta property as null and fulfill it later in then callback of filter request in loadClaims method:

    loadClaims: function () {
        var filteredClaims = this.store.find('claim', { filter: this.get('filter') }),
            self = this;
    
        filteredClaims.then(function(claims) {
            self.set('meta', claims.get('meta'));
        });
    
        this.set('model', claims);
    }
    
  3. As you can see, there is no need for method 'loadClaims', we can describe 'model' as computed property and set meta in here:

    model: function () {
        var filteredClaims = this.store.find('claim', { filter: this.get('filter') }),
            self = this;
    
        filteredClaims.then(function(claims) {
            self.set('meta', claims.get('meta'));
        });
    
        return filteredClaims;
    }.property('filter')
    
  4. Or even simpler:

    model: function () {
       return this.store.find('claim', { filter: this.get('filter') });
    }.property('filter'),
    
    meta: function() {
       return this.get('model.meta');
    }.property('model.meta')
    
  5. (questionable) In my opinion View (template) and data must be maximally separated, so I'd suggest to describe all metadata fields as computed properties of controller:

    model: function () {
       return this.store.find('claim', { filter: this.get('filter') });
    }.property('filter'),
    
    page: function() {
       return this.get('model.meta.page');
    }.property('model.meta.page'),
    
    perPage: function() {
       return this.get('model.meta.per_page');
    }.property('model.meta.per_page'),
    
    totalPages: function() {
       return this.get('model.meta.total_pages');
    }.property('model.meta.total_pages')