Cereal Killer
Cereal Killer

Reputation: 3414

Ember updating array does not update template

I'm going mad with this problem: I have a component with a template that uses a {{#each}} loop to iterate an array of comments;

comments: Ember.computed('commentsModel', function() {
    return this.get('commentsModel').toArray();
}),

actions: {
    addOne: function() {
        this.set('comments', [{content: 'agent k'}]);
    }
}

The component is called like this:

{{photo-comments commentsModel=model.comments}}

Where model.comments is returned by the model hook of the route; When I click the button that triggers "addOne" event, the template updates correctly, all the comments are removed and only the new comment "agent k" is shown;

but if I want to ADD a comment into the comments array, instead of overwriting the whole array, it doesn't work; I get no errors but the template simply ignores it and does not updates!

I tried with push:

actions: {
    addOne: function() {
        this.set('comments', this.get('comments').push({content: 'agent k'});
    }
}

with pushObject:

actions: {
    addOne: function() {
        this.set('comments', this.get('comments').pushObject({content: 'agent k'});
    }
}

nothing! Since this is driving me crazy, can someone tell what's wrong with this?

Template:

{{log comments}}
{{#each comments as |comment|}}
    <div class="card">
        <div class="card-content">
            {{comment.username}}<br>
            {{comment.content}}
        </div>
        <div class="card-action">
            {{comment.createdAt}}
        </div>
    </div>
{{/each}}

Upvotes: 2

Views: 2336

Answers (1)

solocommand
solocommand

Reputation: 327

I think the underlying issue here is that you're misusing the Ember.computed helper.

Your component should define a default value for the comments property, if there is one:

comments: null,

actions: {
    addOne: function() {
        this.get('comments').pushObject({content: 'agent k'});
    }
}

Your template should call the component by passing the model value:

{{photo-comments comments=model.comments}}

Assuming of course, that model.comments is available because it was retrieved by the route's model hook.

In your example code, you would have been attempting to push a new object to a computed property wrapping an array representation of a model, rather than pushing a new value to the model itself.

Upvotes: 3

Related Questions