Request models outside of route or model hook

That is part of the challenge. I need to query the server, which I understand how to do. But the design requirement is to display the search selector ui and the search results table ui on the same page. This is where ember really confuses me.

Also, I imagine something can be done with query params. But managing view hierarchy and talking to multiple models/controllers at the same time is the hard part for me.

Thinking about this a little more I suppose I could use the active hook in one route or controller to load up the the data from another route/controller.

The issue is that I need to get data from a route/controller that will never be directly navigated to.

I just can’t quite figure out the syntax to do this. Basically reach over to the another route/controller and say “hey fetch your data, I need it now”.

This is a very specific case because of the way the models are defined in my domain.

Another statement of the problem here

http://emberjs.jsbin.com/qovusoda/2/

I think you’re clinging to concepts from older routing code that don’t really apply here. I definitely wouldn’t have a search conditions route.

Here’s a potential solution:

In the beforeModel hook of the search route, I would load the search conditions using a promise with a .then() that sets a searchConditions property on the search controller on a successful load.

I would not define a model hook on the search route.

Next, I’d define a search action on the search route that parses the search conditions/terms, performs the ajax call that does the search, and sets the content (and/or multiple other attributes) of the search controller when the ajax call returns.

Then, I would assign the search action to the form on the search template – i.e. <form {{action "search" on="submit"}}>.

Then, I’d render the results of the search action somewhere within the search template.

Make sense?

Thanks @matthooks

Yeah, I think that makes sense overall. I can be really stubborn in my coding patterns. Thanks for the feedback.

I just need to get more sophisticated with my use of promises.

I am still wondering about the case of trying to load two disparate models at the same time. Wonder if it ever makes sense to do something like this:

beforeModel: function() {
  RSVP.Promise.all([
      this.store.find('foo'),
      this.store.find('bar'),
  ]).then(function(values){
    values[0]; // => foos
    values[1]; // => bars

    // do some work to set the controller here
    // ...

    return values;
  });
}

@eccegordo, are you using ember-data? It’s totally ok to push data into your store if you need it, even if you haven’t visited the route. There is no 1:1 mapping between a route’s model and the records you have in the cache, in fact, model used to be named something else, but I can’t remember what.

activate: function(){
  this.generateController('bar');
},
model: function(){
  return this.store.find('foo')
};
afterModel: function(){
  var self = this;
  self.store.find('bar')
  .then(function(bar){
    self.controllerFor('bar').set('model', bar)
  })
},
setupController: function(controller, model) {
   controller.set('needs', ['bar']);
}

Here’s the API

http://emberjs.com/api/classes/Ember.Route.html#method_controllerFor
Returns the controller for a particular route or name.

The controller instance must already have been created, either through entering the associated route or using generateController.

@ulisesrmzroche yes using ember data. That code snippet is very helpful, becoming more clear.

In the case outside of ember data what is the idiomatic way to do this?

Can I just use modelFor rather than store.find()? For example in the case of routes just returning vanilla arrays in their model hook.

// Route Foo
model: function(){
  return ["A","B", "C"];
};

// Route Bar

How do I get the model of Foo?

modelFor('foo')

Reading the docs is seems that modelFor only works for ancestor or parent routes/resources.

Wondering about the non nested case. Here is a JSBin that illustrates the problem

http://emberjs.jsbin.com/lewex/2/

alright man? :frowning:

The concept is the same. If you haven’t visited a route yet, then the model hook won’t be called, and that means the data will come out undefined. In case you are writing a route that needs multiple models, but haven’t transitioned into their corresponding routes yet, then you can push their data into the store when you need it. This probably means that you have a complex route that happens to come in early in your app.

For the most part, you can just call the store and set it to whatever property in your controller that you want. If you want to boost performance, you can generate the supporting controllers beforehand, and seed them. When you actually visit the supporting routes, and you’re using Ember Data you won’t need fetch data. If you are using your own you’ll have to implement some form of caching.

This is usually what I do, although I use Ember.RSVP.hash, and then use controllerFor in setupController if I need to. But you can merge the two arrays and just pass them into your controller. That’s probably the clearest way to accomplish this.

1 Like