0
votes

Hi i have a controller with a drop down which needs location data. I provide this data via a service. The service is working find I know it as dropLocation: alias('loaddropLocation') line works and show all the location with duplicates. But when i change the alias to uniq i expect to get unique array data. but it does not work.

import Ember from 'ember';
const {
    get,
    computed,
}= Ember;
const{
    uniq,
    alias
} = computed;
const {
    service,
} = Ember.inject;


export default Ember.Controller.extend({
  dropLocation: uniq('loaddropLocation'),//first-line
  Dropdata: service(),
  loaddropLocation: computed('Dropdata',function(){
        return get(this,'Dropdata').locations().then((locs) =>{
            return locs;
        });
  }),
})

Updated

I have updated my controller with inputs from @torazaburo .

loaddropData get update with an array. but dropLocation does not. When I click on the controller from ember-inspector the value gets computed and dropLocation gets updated and I see value in my UI. how can I change this behavior. I tried to calculate uniq values from aobservesDropData but it not working.

 export default Ember.Controller.extend({
      dropLocation: uniq('loaddropLocation'),//first-line
      Dropdata: service(),
      dropLocation: uniq('loaddropLocation'),
      loaddropLocation:[],
      observesDropData: function(){
            return get(this,'Dropdata').locations().then((locs) =>{
                this.set('loaddropLocation',locs)
            });
      }).on('init'),
    })

This does not work

  dropLocation:  computed('loaddropLocation', function() {
    return Ember.computed.uniq(get(this,'loaddropLocation'));
  }),

More updates: It seems computed property and promises does not go well together in emberjs. I got few points from ember slack community that locations should be a computed property

//in my service
    locations: computed(function() {
        return get(this,'store')
            .findAll('store')
            .then(stores =>{
                return stores.map(store => {
                     return get(store,'adminAreaLevel2') +" "+ get(store,'adminAreaLevel1')
            }); 
          }

along with

//in my controller 
dropLocation: uniq('Dropdata.locations')

,

does not work because of know issue that cp does not work with promises well.

Alternative I tried was

locations: computed(function() {
        var self = this;
        var locs;
        return get(this,'store')
            .findAll('store')
            .then(stores =>{
                locs =  stores.map(store => {
                     return get(store,'adminAreaLevel2') +" "+ get(store,'adminAreaLevel1')
            });
            set(self,'location',locs);

          }

//same thing in my controller 
dropLocation: uniq('Dropdata.locations'),

this seems to work but not correctly. I am using as input for ember-power-select when i click the dropdown first time. the value is not updated. when i click on dropdrown for second time the value for options are populated.

// trying to create a twiddle for my Problem need to figure out how to mock data for services and add ember-power-select addon to twiddle

1
You could write const {get, computed: {uniq, alias}, inject: {service} } = Ember;, but whatever. Also, (locs) => { return locs; }) is equivalent to locs => locs which of course is equivalent to not writing it at all.user663031

1 Answers

0
votes

You cannot return a promise as the value of a computed property. It might work depending on how it is being consumed downstream--for instance, a template might be able to emit it--but uniq certainly does not know how to deal with a promise as input, which is what you are doing.

An imperfect alternative is to observe the dependency, then set the property in the object when the promise fulfills:

dropLocation: uniq('loaddropLocation'),//first-line
Dropdata: service(),
observeDropdata: observe('Dropdata', function(){
  get(this,'Dropdata').locations().then(locs => this.set('loaddropLocation, locs));
})

Minor points:

You could write

const {get, computed: {uniq, alias}, inject: {service} } = Ember;

Also, in your original code (locs) => { return locs; }) is equivalent to locs => locs which of course is equivalent to not writing it at all.