Reputation: 167
I am trying to loop over some objects in Ember in a controller, and return an array of their name attributes. I am however confused with what Ember is returning from the findAll function.
In a controller, I have the following function -
possibleGenres: function() {
var genres = this.store.findAll('genre');
var genreNames = genres.map(function(item, index, enumerable){
return item.get('name');
});
return genreNames;
}.property(),
Logging genres.get('length') gives me 0.
I have proven that there are genres available in the findAll function, as when returning the returned genres from just the findAll function, they are displayed in the template.
Am I misunderstanding something crucial about Ember controllers here?
As ever, any help is much appreciated.
Upvotes: 2
Views: 736
Reputation: 9624
As others have stated, the problem is that findAll
returns a promise, so you will have to use .then()
to wait until the promise is resolved before the data is available to work with.
I think a cleaner way to approach this would be to set genres
as a property and then have genreNames
as a computed property that observes the genres
array. Note, that Ember automatically unwraps promises when computed properties return them, so you don't have to use .then()
in this situation:
export default Ember.Controller.extend({
genreNames: Ember.computed.mapBy('genre', 'name'),
genres: function() {
return this.store.findAll('genre');
}.property()
});
Upvotes: 2
Reputation: 167
Since findAll was returning a promise, as pointed out by lukkysam, the correct solution would be to use then
on the returned value like so.
possibleGenres: function() {
var genreNames = [];
this.store.findAll("genre").then(function(genres){
genres.forEach(function(genre){
genreNames.push(genre.get('combinedName'));
});
});
return genreNames;
}.property(),
Upvotes: 0
Reputation: 188
Perhaps
this.store.all("genre") works better for you.
findAll will return a Promise, not the records you want. if you try
genres.then(function(result){
var genreNames = result.map(function(item, index, enumerable){
return item.get('name');
});
you will have your results.
the problem is, that it's asynchronous. genreNames will be undefined, while you return it. You could start a workaround with an observer, to solve this problem.
f.e.
possibleGenres: [],
possibleGenresDidChange: function(){
//code...
this.set("possibleGenres",result);
}.obersves("possibleGenresTrigger"),
possibleGenresTrigger: false,
to update the property, switch the TriggerState between true and false. But it's a bit ugly. I do it some times the same way, because I found no better solution handling asynchronous requests in Controllers.
But, like written in the first line, perhaps store.all() works fine for you.
Upvotes: 0