0

I have an EmberJS controller that has the following computed property:

hasSelectedRequirements: Ember.computed('selectedRequirements.[]', function()    {
    console.log("this should get printed but it doesn't");
    return this.get('selectedRequirements').length > 0;
}),

which sets a boolean flag I am using in a template to conditionally display html.

I also have a button, that, when clicked, takes the form data and pushes an element onto the selectedRequirements array by calling the addRequirement action

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);
        this.set('selectedRequirements', selectedRequirements);

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

If I change the addRequirement function to this instead, then the hasSelectedRequirements computed property's function handler is run as expected, and the console.log statement works:

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);

        // create a new, local array
        var arr = new Array();
        arr.push(1);

        this.set('selectedRequirements', arr);

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

It seems as though Ember's computed properties rely upon the array that is being observed being a completely different array?

The problem is that the computed property is not recognizing that an element was added to the selectedRequirements array, and the computed property function never gets called (the console.log statement never runs). Why does the computed property not recognize that the selectedRequirements array has been modified and how can I fix the computed property code?

1
  • 1
    Why don't you just use hasSelectedRequirements: Ember.computed.bool('selectedRequirements.length')? By the way, use pushObject, not push. Commented Jul 7, 2016 at 19:57

3 Answers 3

3

Use pushObject like this.get('selectedRequirements').pushObject(obj);

Sign up to request clarification or add additional context in comments.

2 Comments

The pushObject method in the Ember MutableArray class is exactly what I was looking for. I can't tell you how long I searched and couldn't find an answer to this problem though. I knew what the underlying issue was but not the Ember solution. Hopefully this post helps others.
@lkgarrison Cool. So if this issue is solved please kindly accept my post as answer
1

It seems that Ember's computed properties (at least observing using the array.[] syntax) require a new array in order to recognize changes. Thus, the best solution I have found is to create a copy of the array using slice:

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);
        this.set('selectedRequirements', selectedRequirements.slice(0));

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

This guarantees that the hasSelectedRequirements computed property is set appropriately each time the addRequirement action is called

Comments

0

using pushObject instead of push and removeObject instead of splice will trigger the computed property.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.