Alan Dong
Alan Dong

Reputation: 4095

Ember Component loads store data

Which life cycle do you think is the most appropriate place to load store data in Ember.Component?

I’m loading data asynchronously. That’s why I’m not loading the real data from route, but its meta-data?

For example. I'm loading a list of books, thats based on Author's name, and a list of publisher. (This is just an illustration).

I get a a list of authors, and a list of publishers.

Codes:

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return Ember.RSVP.hash({
      authors: this.store.findAll('author'),
      publishers: this.store.findAll('publisher')
    });
  }
})

After fetching authors and publishers from the route, now we can do another query, namely this.store.find('book', {author, publisher}) to get a book.

I just wanted to ask to see which life cycle in Ember.Component is more appropriate to fetch such data asynchronously.

Update:

This issues can be solved by putting the loading logics in the following 3 ways:

  1. In setupController inside route.

  2. In model() hook of route

  3. In component life cycle.

After consideration (reading and discussing with colleagues), I think Component should be putting result, not the logics. See my answer below.

Upvotes: 1

Views: 1172

Answers (2)

Alan Dong
Alan Dong

Reputation: 4095

I was able to chain it.

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return Ember.RSVP.hash({
      m1s: this.store.findAll('meta1'),
      m2s: this.store.findAll('meta2')
    }).then( ({m1, m2}) => {

      let data = [];
      m1s.forEach( (m1) => {
        m2s.forEach( (m2) => {    
          this.store.query('modelName', {
              m1.get('id'),
              m2.get('id')
          });

        });

      });

    });
  }
}),

You might need to write your own adapter and serializer though.

Upvotes: 0

kiwiupover
kiwiupover

Reputation: 1780

The init() hook is where you want to make the request for data.

import Component from 'ember-component';
import injectService from 'ember-service/inject';

export default Component.extend({
  store: injectService(),

  posts: [],

  init(){
    this._super(...arguments);

    this._getPosts();
  },

  _getPosts() {
    this.get('store').findAll('post').then((posts) => {

      // because this is async you need to guard against the component 
      // being destroyed before the api call has finished because 
      // because `this.set` will throw an error.
      if (this.isDestroyed) { return; } 

      this.set('posts', posts);
  }
});

Upvotes: 2

Related Questions