Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise result in Ember Data computed property

I'm trying to make a call to an external API and use the results as a computed property in my Ember Data model. The result is fetched fine, but the computed property returns before the Promise resolves, resulting in undefined. Is this a use case for an Observer?

export default DS.Model.extend({
  lat: DS.attr(),
  lng: DS.attr(),
  address: Ember.computed('lat', 'lng', function() {
    var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
    var addr;

    var request = new Ember.RSVP.Promise(function(resolve, reject) {             
        Ember.$.ajax(url, {                                                        
          success: function(response) {                                            
            resolve(response);                                                     
          },                                                                       
          error: function(reason) {                                                
            reject(reason);                                                        
          }                                                                        
        });                                                                        
     });                                                                          

     request.then(function(response) {                      
       addr = response.results[0].formatted_address;                              
     }, function(error) {                                                         
       console.log(error);
     })  

     return addr;
  })
});
like image 263
codyjroberts Avatar asked Oct 29 '25 08:10

codyjroberts


1 Answers

Use DS.PromiseObject. I use the following technique all the time:

import DS from 'ember-data';

export default DS.Model.extend({

  ...

  address: Ember.computed('lat', 'lng', function() {
    var request = new Ember.RSVP.Promise(function(resolve, reject) {             
      ...
    });                                                                          

    return DS.PromiseObject.create({ promise: request });
  }),

});

Use the resolved value in your templates as {{address.content}}, which will automatically update when the proxied Promise resolves.

If you want to do more here I'd recommend checking out what other people in the community are doing: https://emberobserver.com/?query=promise

It's not too hard to build a simple Component that accepts a DS.PromiseObject and show a loading spinner while the Promise is still pending, then shows the actual value (or yields to a block) once the Promise resolves.

I have an Ember.Service in the app I work on that's composed almost entirely of Computed Properties that return Promises wrapped in DS.PromiseObjects. It works surprisingly seamlessly.

like image 101
Max Wallace Avatar answered Oct 31 '25 21:10

Max Wallace



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!