iron-meteor / iron-router

A client and server side router designed specifically for Meteor.
MIT License
1.98k stars 412 forks source link

Navigating to the same action with different params doesn't rerender. #310

Closed andrenanninga closed 10 years ago

andrenanninga commented 10 years ago

Hey Guys,

I'm having a problem with the rerendering when I follow a link from an action to the same action but with other parameters.

I'm using a route similar to this:

this.route('question', {
    path: '/question/:question_number',
    controller: 'QuestionnaireController',
    action: 'actionQuestion'
});

In the controller I am using this.getData() to update the data for the template, I don't know if this is relevant or not. The action looks like this:

actionQuestion = function() {
    var data = this.getData();
    var questionNumber = parseInt(this.params.question_number, 10);

    data.question = question.findOne({ number: questionNumber });

    this.render();
}

with this I have a link to /question/3 which brings you to the third question in the questionnaire. Then on that page there is a link to the nest question: /question/4. when I click on that link the action is triggered but the page itself isn't rerendered.

Any pointers on how I can get this to work?

Thanks.

tmeasday commented 10 years ago

Hey @FakeYou

If you want it to be reactive (and thus re-render), I'd suggest calling this.setData() rather than just changing the data object.

But as a larger question, can I ask why are you setting data like this and not using a data option?

this.route('question', {
    path: '/question/:question_number',
    controller: 'QuestionnaireController',
    data: function(){ 
      return {
        question: question.findOne({ number: parseInt(this.params.question_number, 10)}); 
     }
});
andrenanninga commented 10 years ago

I tried using this.setData() but it would cause an infinite loop where it would constantly call the action again and again similar to issue #234.

After reading that issue more thoroughly I came across your comment saying that you should set data: false in the route to prevent the infinite loop.

My route now looks like this:

this.route('question', {
    path: '/question/:question_number',
    controller: 'QuestionnaireController',
    action: 'actionQuestion',
    data: false
});

and the action I'm using this.setDate({ question: question.findOne( ... )}); to set the question and that's working without issues.

This method does however prevent you from using both a data method in your controller and set extra data specific to the current action which might cause issues later.