Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iron.controller is not reactive in all cases #1232

Open
mitar opened this issue Feb 14, 2015 · 9 comments
Open

Iron.controller is not reactive in all cases #1232

mitar opened this issue Feb 14, 2015 · 9 comments

Comments

@mitar
Copy link
Contributor

mitar commented Feb 14, 2015

If you have two routes with the same template set, then Iron.controller().getParams() is not rerun if the URL (and thus params) change. Maybe the problem is that getParams is not reactive. So if I use the same template but different URLs for different params, template helper is not called again for new params.

See reproduction: https://github.com/mitar/ironrouter-issue1232

@kontur
Copy link

kontur commented Feb 18, 2015

Ran into what I believe to be the same issue with two routes that use the same template, but one of them passes in a data object, when the other runs without. The render functions are called, the template is just not re-rendered on the second route.

Seems rather unlikely that simply having the same template for two routes wouldn't trigger a new render, but can it be?

Is there any way to force a route's template to re-rendered, as a work around to be used?

@kontur
Copy link

kontur commented Feb 19, 2015

For now I used a reactive var / session variable in the route controller and execute the template rendered function when it changes by accessing it in the template rendered function. :/

Anybody with more insight to iron router got an idea where to start with this issue?

@mcrayne
Copy link

mcrayne commented Mar 19, 2015

Edit : don't pay any attention to my response below, though learning more about the Tracker module was helpful, my problem was I needed to put the function to update data in the template in helpers and not in the onRendered() callback. I was confused because it would work intermittently and I thought that since the router_controller was rendering the template it would refresh for each new /:id url passed. It doesn't. Anyways, moving the lookup and load logic into the template.myTemplate.helpers() there were no more problems.

I am still fairly new so this may not be best pattern, but, after searching everywhere for a solution to this, it does appear that you DO need to set a session variable as @kontur states - but, under 1.0.4 I could not get the onRendered(...) to run again even though I referenced the Session variable in the callback and could verify it was changing, though not triggering a new rendering.

I was only able to solve that by wrapping the callback with Tracker.autorun

 onRendered( function () {
     Tracker.autorun( function() {
        Session.get('myVar') ...   })
});

It makes sense when you watch how the events are raised (onRendered for example) but it would be nice not to have to wrap the callback and just count on the reactive Session variable.

@kontur
Copy link

kontur commented Mar 23, 2015

I tried look into this a bit more, but I just lack insight into iron router :/ Can't even tell if the component in the wrong here is router, controller or layout. Any input? 👍

@niranjans
Copy link

+1. Have the same issue. When I do a Router.go() within the same template but with different query params, the params object does not seem to be reactive.

@keviniamburg
Copy link

+1

2 similar comments
@kokjinsam
Copy link

+1

@romiohasan
Copy link

+1

@ciclopes
Copy link

Well, I believe I was having kinda the same issue.
Here is what I've done to force a template update upon a same route params change:

## router.coffee
Router.route '/profile/:_id',
  name: 'profile'
  action: ->
    Session.set 'profileId', @params._id
    @render 'profile'

## profile.coffee
Template.profile.onCreated ->
  @user = new ReactiveVar
  template = @

  @autorun ->
    template.subscription = template.subscribe 'profile', Session.get 'profileId'

    if template.subscription.ready()
      template.user.set Meteor.users.findOne _id: Session.get 'profileId'
    else
      console.log 'Profile subscription is not ready'

Template.profile.helpers
  user: -> Template.instance().user.get()

## profile.html
<template name="profile">
  {{#if user}}
    {{#with user.profile}}
      <span class="first-name">{{firstName}}</span>
      <span class="last-name">{{lastName}}</span>
    {{/with}}
  {{else}}
    <span class="warning">User not found.</span>
  {{/if}}
</template>

The main point here is the Session variable inside the subscribe call, which in turn is in the autorun call (profile.coffe file). Since the Session variable is a reactive data source, the subscription will be updated as well as the template, causing the latter to be rerendered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants