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;
})
});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With