Reputation: 3174
I'm gathering some ajax data and want to populate a list with it. The data source is from LastFM's API - I know I'm receiving the data - see the image:
Here's the code I'm using - any advice on best practice would be appreciated also - I'm enjoying Ember, but to be honest am still feeing my way around the way it works:
App.IndexRoute = Ember.Route.extend({
model: function () {
var albumArtwork = [];
function convertString (data) {
return encodeURIComponent(data).replace(/%20/g, "+");
}
$.each(topAlbums, function (i, el) {
var request = 'http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=[REMOVED API KEY!]&artist=' + convertString(topAlbums[i].artist) + '&album=' + convertString(topAlbums[i].album) + '&format=json';
$.ajax({
'url': request
}).done(function (d) {
albumArtwork.push(d.album.image[1]['#text']);
});
});
albumArtwork = _.toArray(albumArtwork)
return albumArtwork;
}
});
<script type="text/x-handlebars" id="index">
<div class="album-artwork-list-wrapper">
<ul class="album-artwork-list">
{{#each item in model}}
<li class="album-artwork-item">
<img src="{{item}}">
</li>
{{/each}}
</ul>
</dv>
</script>
Here's what I think is happening: The handlebars template is being rendered before the data comes back from the API call. How to overcome this with Ember JS, I'm not certain - I have seen examples of a solution here on stackoverflow and attempted to use them but to no avail!
Many thanks for your help in advance!
Upvotes: 2
Views: 1443
Reputation: 13379
you have to create promises so that async calls can become synchronised. Ember provides RSVP.js to do the same. RSVP.all fits your purpose. So..your code can be changed like this.
App.IndexRoute = Ember.Route.extend({
model: function () {
var albumArtwork = [], promises =[];
function convertString (data) {
return encodeURIComponent(data).replace(/%20/g, "+");
}
$.each(topAlbums, function (i, el) {
var request = 'http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=[REMOVED API KEY!]&artist=' + convertString(topAlbums[i].artist) + '&album=' + convertString(topAlbums[i].album) + '&format=json';
promises.push(ajaxPromise(url));
}
return RSVP.all(promises).then(function(images) {
// images contains an array of results for the given promises
albumArtwork = images.filterBy('album');
return albumArtwork;
});
});
var ajaxPromise = function(url, options){
return Ember.RSVP.Promise(function(resolve, reject) {
options.success = function(data){
resolve(data);
};
options.error = function(jqXHR, status, error){
reject(arguments);
};
Ember.$.ajax(url, options);
});
};
Upvotes: 5