Reputation: 449
I'm trying to return data from an Ajax call in a computed property. I understand because of the asynchronous nature, I can't do the following. However, I can't return a promise because I need to return the data in a particular format of an array with objects with a property and label.
options: Ember.computed('name', function() {
let id = name.id;
const url = '/testUrl/id=' + id;
let optionArray = [];
Ember.$.ajax({
url: url,
type: 'GET',
}).then((response) => {
let arr = JSON.parse(response);
for (let idx = 0; idx < arr.length; idx++) {
optionArray.addObject({
property: idx,
label: arr[idx]
});
}
return optionArray;
});
})
How do I return the data from the Ajax call in the format specified above?
Upvotes: 0
Views: 841
Reputation: 66
You could always initiate the AJAX request within the init
method of your component/controller. It is typically best practice to load data on the model from the route, but there are occasionally instances where this sort of pattern tends to make things easier:
init() {
this._super(...arguments);
this.options = {};
this.getAndSetOptions();
},
getAndSetOptions() {
/* Make AJAX request and modify result as needed */
Ember.set(this, 'options' result);
}
Also, to handle asynchronous behavior (promises, callbacks, etc.) in your Ember app I would suggest checking out Ember Concurrency.
Upvotes: 0
Reputation: 288
In general, it is a bad practice to have ajax calls in a computed property -- try having it in your model in the route, and pass the data down to your component (or wherever you are using your options property). I see you are observing 'name' -- is there a reason you are doing that? Since the url seems to be the same no matter the name, it seems like you don't need the computed property at all. That said, a computed property always needs to return something. So the only way I can think of making this work would be to return the promise in the computed property and then use it somewhere else in your code - maybe another function, wait for it to resolve in there and then set the optionArray.
To reiterate, I feel like you should ask yourself if you really need this logic in a computed property or if you can do it in a route. If not a route, at least in a function or another hook. If you provide more context, I can maybe help you better.
Upvotes: 3