Using promises with computed properties?


#1

Hey everyone,

I’m trying to use a computed property to return models when an array of ids changes on a service. It looks like this:

people: computed('ids', function() {
    const promises = this.get('ids').map(id => {
      return this.get('store').findRecord('people', id);
    });

    return new Ember.RSVP.Promise((resolve) => {
      Ember.RSVP.allSettled(promises).then(responses => {
        const results = [];
        responses.forEach(prom => {
          if (prom.state === 'fulfilled') {
            results.push(prom);
          }
        });
        resolve(results);
      });
    });
})

However, this does not end up showing up in the template. Any ideas why?


#2

Yes. Ember templates does not automatically resolves promise. There’s a workaround though.

Ember Data comes with the DS.PromiseArray and DS.PromiseObject class, which you can use to wrap your promise so it becomes bindable.

people: computed('ids', function() {
  const promises = this.get('ids').map(id => {
    return this.get('store').findRecord('people', id);
  });

  return DS.PromiseArray.create({
    promise: new Ember.RSVP.Promise((resolve) => {
      Ember.RSVP.allSettled(promises).then(responses => {
        const results = [];
        responses.forEach(prom => {
          if (prom.state === 'fulfilled') {
            results.push(prom);
          }
        });
        resolve(results);
      });
    });
  });
})
{{#if people.isFulfilled}}
  {{#each people as |person|}}
    {{person.name}}
  {{/each}}
{{else if people.isRejected}}
  {{people.reason}}
{{/if}}

#3

There is a good article on this subject here:

https://emberigniter.com/guide-promises-computed-properties/