简体   繁体   中英

Ember - Get Value From Ember Data Array

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.

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()
});

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.

fe

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.

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(),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM