0
votes

My model has 2 attributes (baseCurrency and otherCurrencies) whose values are selected in a form by 2 ember power selects dropdown menu whose options depend on 2 computed properties (baseCurrencyOptions and otherCurrencyOptions)

controller

  ...
  otherCurrencyOptions: Ember.computed('model.baseCurrency', function() {
    console.log(`allCurrencies changed to: ${this.get('allCurrencies')}`);
    return Ember.A(this.get('allCurrencies')).removeObject(this.get('model.baseCurrency'));
  }),
  baseCurrencyOptions: Ember.computed('model.otherCurrencies', function() {
    console.log(`allCurrencies changed to: ${this.get('allCurrencies')}`);
    return Ember.A(this.get('allCurrencies')).removeObjects(this.get('model.otherCurrencies'));
  })
  ...

allCurrencies property contains a list of all currencies and it is not supposed to change over time.

template

{{#power-select searchEnabled=true options=baseCurrencyOptions selected=model.baseCurrency onchange=(action (mut model.baseCurrency) as |currency|}}
  {{currency}}
{{/power-select}}
{{#power-select-multiple searchEnabled=true options=otherCurrencyOptions selected=model.otherCurrencies onchange=(action (mut model.otherCurrencies)) as |currency|}}
  {{currency}}
{{/power-select-multiple}}

Problem is that every time I select a currency in one or the other of both dropdown menus allCurrencies property gets updated loosing in an irreversibile manner every selected currency. I expected Ember.A() to create a brand new object without modifying `allCurrencies!. Moreover I got the following warning:

DEPRECATION: You modified concatenatedTriggerClasses twice in a single render. This was unreliable in Ember 1.x and will be removed in Ember 3.0 [deprecation id: ember-views.render-double-modify]

1

1 Answers

0
votes

Ember.A will not create brand new Arrayit will just implements Ember.Enumerables and array interfaces(reference).

Here is my suggested options,

1)To create brand new Array, you can use toArray method. so change this Ember.A(this.get('allCurrencies')) to this.get('allCurrencies').toArray()

2)Another option is, iterate allCurrencies using forEach and inside callback use iterate baseCurrency to check for the condition and fill otherCurrency Array.

var baseCurreny = this.get('model.baseCurrency');
var otherCurrency = [];
this.get('allCurrencies').forEach(function(item, index, self) {
    /*I assume id as your unique property to identify object
    if (!baseCurrency.findBy('id', item.id)) {
        otherCurrency.pushObject(item);
    }*/
    //or if its plain string then
    baseCurrency.forEach(function(baseItem) {
        if (item !== baseItem) {
            otherCurrency.pushObject(item);
        }
    });
});
  1. Define Array of Currency object like [{id:1,name:'Dollar',type:'base'},{id:2,name:'Yen',type:'other'}] so that you can use computed macros to get baseCurrencies and otherCurrencies
    baseCurrencies:Ember.computed.filterBy('allCurrencies','type','base')
    otherCurrencies:Ember.computed.filterBy('allCurrencies','type','other')