33

in Ember.js I have route with model. Could you help me, when I'm on route playlist how to reload this route (or set new data to model) called by callback from another JS function? I've been looking to documentation so long, but no help for me.

App.PlaylistRoute = Ember.Route.extend({
 setupController: function(controller, model) {
  $.getJSON('api/playlist.php?' + Math.random().toString(36), function (data) {
   controller.set('model', data);
  });
 }
});

Thanks a lot!

real_ate
  • 10,861
  • 3
  • 27
  • 48
honzahommer
  • 839
  • 3
  • 10
  • 15

4 Answers4

78

It seems the solution in the answer won't work for current route. I had a same issue and tried the solution here and it worked.

http://discuss.emberjs.com/t/refresh-current-view-page-after-language-change/4291/5#post_5

In your route.

actions: {
  sessionChanged: function() {
    this.refresh();
  }
}

and in your controller.

observeSession: function() {
  this.send("sessionChanged");
}.observes("session.isAuthenticated"),
Atsuhiro Teshima
  • 1,508
  • 1
  • 12
  • 21
  • 4
    Unfortunately I've tried this and nothing happens. I'm not using any model on the route, I just need it to rerender; but nothing seems to work. – Bogdan Zurac May 16 '15 at 08:21
  • The same idea all within the route file: ``` afterModel() { this.get('session').on('sessionAuthenticated', () => { this.refresh(); }); } ``` – huntie Jun 04 '16 at 18:23
  • Perfect. Note that the `this.send("sessionChanged");` line alone will trigger the fresh from anywhere in the controller. – Charney Kaye Jan 23 '17 at 01:13
  • Important: The controller's action and the rout's action must not have the same name – crusy Apr 06 '18 at 11:53
9

There are two ways of doing it.

One is write an action in playlist route and call this.refresh() inside it For more information you can visit Ember Guide refresh method for route.

The other way is in your controller depending on the situation when you need to reload your route use

this.get('target.target.router').refresh();

any of the two would help you in refreshing your route.

A small note of refresh method below from ember guides:

Refresh the model on this route and any child routes, firing the beforeModel, model, and afterModel hooks in a similar fashion to how routes are entered when transitioning in from other route. The current route params (e.g. article_id) will be passed in to the respective model hooks, and if a different model is returned, setupController and associated route hooks will re-fire as well.

Rimian
  • 36,864
  • 16
  • 117
  • 117
Sumit Surana
  • 1,554
  • 2
  • 14
  • 28
  • 2
    Note for me it was `this.get('target.router').refresh()`. In addition, calling `refresh` on the route seems to be refreshing both parent and child routes of the route being refreshed (so the refresh is bubbling up all the way to the application route). – Sarus Dec 12 '15 at 18:56
  • The other third way is just to change the data using this.model.set() and let the template change as a result. e.g this.playlist.set('content', newplaylist) (assuming an ArrayProxy). – Epirocks Sep 28 '20 at 15:46
7

From a controller use transitionToRoute:

this.transitionToRoute('playlist', newModel);

From a route use transitionTo:

this.transitionTo('playlist', newModel);

For example, imagine you have an action on your controller

App.PlaylistController = Ember.ArrayController.extend({
 actions: {
   grabNewModel: function(){
     //get some new model
     this.transitionToRoute('playlist', newModel);
   }
 }
});
Michael
  • 1,502
  • 19
  • 29
Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
  • 1
    Ember.Controller.transitionToRoute doesn't seem to reload the current route. I have LOG_TRANSITIONS_INTERNAL on and all it does 'Attempting transition to index' and finishes. Stepping into the transitionToRoute code now... – Jinyoung Kim Mar 15 '14 at 14:03
  • You need to send it a different model, if you're sending the current model then there isn't a legitimate reason for reloading the route. What are you trying to accomplish? – Kingpin2k Mar 15 '14 at 19:33
  • 1
    Use case: When you define your model in route "/foos" as a list (for example with ember-data's `findQuery`), create a model of the same Class in another route "/foos/new" and then redirect back to "/foos" using `Route#transitionTo`, the newly created model won't appear because neither the `model()` hook nor `setupController()` are exectuted on "/foo". This behavior can be observed when using a route with dynamic segments and running `transitionTo 'foo', 23`. So how do we force the "/foo" route to reload its `model()`? – Niklas Hofer Mar 28 '14 at 18:49
  • If you've created a new model that you know is a part of another resource, you should just add it to that resource when appropriate (aka after save, or create, or whenever makes sense). There is no need to reload the entire route, that's far more expensive than just adding another item to the collection. Additionally you can issue the `find({foo:'red'})`, but return `store.filter(filterFunc)` which is an live record array (meaning as data changes/new data enters the system the collection updates with the new records) – Kingpin2k Mar 28 '14 at 21:54
  • 2
    ^^ This is a poor solution. It would work, but defeats a major purpose of Ember which is to handle all this sort of crap for you. What if there were several collections that this new record should be a member of? The above solution would require intimate knowledge of every location the new record needs to be inserted, whereas simply reloading the route would automatically handle everything. Further, what if there's a new record on the server that the client doesn't have yet, and we just want to be sure we have fresh data? Or if the route's model is a hash with multiple records or collections? – KOGI Feb 05 '15 at 19:16
  • 2
    Regardless of when the answer was written, it is currently true that this is a poor solution. As stated, it will work, and at the time may have been the only option, but is not a good solution any longer. I didn't downvote you or your answer either, so just chill. :) – KOGI Feb 05 '15 at 21:10
1

This answer appears first on google when searching how to refresh a route with the current accepted answer being out of date. If you really need to refresh a route and perform the model hook action again from an action in a controller then use the following:

In the route

@action
refreshModel() {
  this.refresh();
}

In order to call this action in the controller use

this.send('refreshModel');

For example:

@action
performUpdate(event) {
  event.preventDefault();
  // Perform necessary action
  this.send('refreshModel');
}

Note: This will send the action to the corresponding route for the controller it is called from, and update that route only and any child routes.

Chris Parry
  • 124
  • 2
  • 10