Eswar
Eswar

Reputation: 77

how to reduce the load in model hook in Ember

I have a routes/paper.js file which has below model hook

model(params,transition){
   let user = store.getRequest('user','paper/user')
   let address = store.getRequest('address','paper/address')

return RSVP.hash({
   user,
   address
}).then((model) => {
    set(model, 'address_name', get(model.address, 'name'));

    return ...model
})

}

I want to reduce the load in model hook by moving the api request to controller and use it in setcontroller . but the model is not having the data , please find below my modification

//controller/paper.js

testerfunction(params){
 let user = store.getRequest('user','paper/user')
   let address = store.getRequest('address','paper/address')
   let paperId = params.paperID

return RSVP.hash({
paperID: paperID,
   user,
   address
}).then((model) => {
    set(model, 'address_name', get(model.address, 'name'));

    return ...model
})

}


//routes/paper.js 


model(params,transition){

}


setupController(controller,model) {
 testerfunction(get(this,'model.params');
}

but my page render is blank

Upvotes: 0

Views: 176

Answers (2)

Devman
Devman

Reputation: 310

I'd recommend using ember-concurrency. Your Route would end up looking something like:

loadUser: task(function * () { return store.getRequest('user','paper/user') })
loadAddress: task(function * () { store.getRequest('address','paper/address') })
loadAddressName: task(function * (addressPromise) {
  const address = yield addressPromise
  return get(address, 'address_name')
})
model(params, transition) {
  const address = this.loadAddress.perform()
  const user = this.loadUser.perform()
  const address_name = this.loadAddressName.perform(address)
  return {
    user,
    address,
    paperID: params.paperID
  }
}

As an added bonus, you get a loading status for each one in your controller/template so you can do things like:

{{#unless model.user.isLoading}}
  {{model.user.name}}
{{else}}
  Some loading state
{{/unless}}

Another option would be to add a loading template that is rendered while the model hook is loading. You just have to add a template next to you main template called your_template_name_loading.hbs

Upvotes: 1

Gaurav
Gaurav

Reputation: 12796

The default implementation of setupController is:

setupController(controller, model) {
  set(controller, 'model', model);
}

Therefore you have two options, you can call the default implementation using _super, or you can reimplement it. Also note that you need to make params part of the object returned from the model hook. Finally, your testerfunction returns a promise. While model expects you to return a promise, setupController does not.

model(params) {
  return { params };
}

setupController(controller, model) {
  return testerfunction(get(this, 'model.params')).then(resolvedModel => {
    this._super(controller, resolvedModel);
  });
}

For more information about setupController, see https://api.emberjs.com/ember/2.18/classes/Route/methods/setupController?anchor=setupController

I've written this answer to be compatible with Ember 2.x based on your code but please in the future let us know which version of Ember you are using.

Upvotes: 1

Related Questions