Search code examples
ember.jsember-datahandlebars.js

Ember template not updating from arraycontroller


In my app, a user can enter a description of a friend or upvote a description that is already present. Both methods (createDescription and upvoteDescription) persist in the database. upvoteDescription changes the DOM, but createDescription does not. It may be because I'm passing a parameter in the model, but I can't get around that -- the api needs it.

//descriptions route

App.DescriptionsRoute = Ember.Route.extend({
  ...
  model: function () {
    var store = this.get('store'),
        friend = this.modelFor('friend');
    return store.find('description', {friend_id: friend.id});
  }
})

//descriptions controller

App.DescriptionsController = Ember.ArrayController.extend({
  ...
  actions: {
    createDescription: function () {
      var name = this.get('name'),
          friend_id = this.get('controllers.friend').get('id'),
          store = this.get('store'),
          description = store.createRecord('description', {
            name: name,
            friend_id: friend_id
          });
      description.save();
    },
    upvoteDescription: function (description) {
      var count = description.get('count');
      description.set('count', count + 1);
      description.save();
    }
  }
});

//descriptions template

{{input value=name action="createDescription" type="text"}}

{{#each controller}}
    <div {{bind-attr data-name=name data-count=count }} {{action upvoteDescription this}}>
        <div>{{name}}</div>
        <span>{{count}}</span>
    </div>
{{/each}}

Solution

  • find (by query) doesn't actively make sure it has the records that match the query, so you'll have to manually inject it into the results.

    createDescription: function () {
      var name = this.get('name'),
          friend_id = this.get('controllers.friend').get('id'),
          store = this.get('store'),
          description = store.createRecord('description', {
            name: name,
            friend_id: friend_id
          });
      description.save();
      this.pushObject(description);
    },
    

    or you can use a live record array (filter/all)

      model: function () {
        var store = this.get('store'),
            friend = this.modelFor('friend');
        store.find('description', {friend_id: friend.id});
        return store.filter('description', function(record){ 
           return record.get('friend_id') == friend.id;
        });
      }