FlowRouter getParam(name) returned wrong reactive value

I’m asking here, as Arunoda suggesting me. Maybe Im using it wrong. Reposting here my issue from flow-router github:
Please look at https://github.com/krizka/flow-rerender/tree/master/client
To reproduce the strange, please follow:

  1. run meteor
  2. open localhost:3000
  3. open dev console
  4. click ‘Foo 1’ link, you will see
flow-rerender.js:6 Foo created - onCreated
flow-rerender.js:9 Foo autorun 1 - autorun in onCreated with param 1 called
flow-rerender.js:22 Foo.foo helper Hello - foo helper run here
flow-rerender.js:9 Foo autorun 1 - and autorun again
  1. Click ‘Bar 1’ link then
flow-rerender.js:29 Bar created - onCreated
flow-rerender.js:32 Bar autorun 1 - autorun with WRONG param 1, returned by FlowRouter.getParam('id')
flow-rerender.js:35 Bar with id 1 not found!!!(anonymous function) @ flow-rerender.js:35(anonymous...
flow-rerender.js:45 Bar.bar helper undefined - if we get the state from id in the url, then we will return wrong data here
flow-rerender.js:32 Bar autorun 2 - and! autorun running again with right ID value

Hope this will help. For further details please ask, or look right to the code, it is pretty simple.

The problem is, your helper is depending on a value this.foo or this.bar that is not reactive

To fix it, you could first meteor add reactive-var and then change the foo and bar assignments and resolving like this:

Template.Bar.onCreated(function () {
  console.log('Bar created');
  // initialize the reactive variable
  this.bar=new ReactiveVar()
  this.autorun(() => {
    const id = FlowRouter.getParam('id');
    console.log('Bar autorun', id);
    // set it properly
    this.bar.set(BARS[+id]);
    if (!this.bar.get())
      console.error("Bar with id", id, 'not found!!!');
  });
});

Template.Bar.helpers({
  bar () {
    // get the variable properly
    var bar = Template.instance().bar.get();
    console.log('Bar.bar helper', bar);
    return bar;
  }
});

Now you will see that it works as expected.

If you think I did not miss something and this indeed is correct, it would be awesome if you could also update your repo and the issue on @arunoda’s repo with this information.

Otherwise let me know what’s still bothering you, or whatever I missed, and let’s work towards fixing it.

Cheers!

1 Like

Thanks for the reply. The problem is not something is not reactive like foo and bar variables.
If you click Foo1 and then Bar2, you will se, that Bar 2 firstly received id 1 as result of getParam, but it is totally wrong, we already in the onCreated of the Bar template, which is rendered with /bar route. And id already have to be id 2.
Maybe I described it wrong. But I tried to explain it to Arunoda too. It is from here: https://kadira.io/academy/meteor-routing-guide/content/accessing-the-url-state. getParam is reactive and must restart autorun on url change. But then we receive wrong result on url change.

No problem, I’d like to help.

Please re-read my answer carefully and make sure you do try the code I provided. It does fix the condition you are describing.

I am referring to this.bar and this.foo which you initialize within your onCreated callbacks.

They are not reactive.

But, you are trying to set them to a value that you obtain reactively from getParam and the helper receives the value within the next flush cycle where your data context gets a second update.

To fix this, I suggested that you use a reactiveVar to replace this.foo with this.foo.set(args) which gets resolved and set within a single flush cycle.

The tracker manual does a good job in explaining how this works. Also, the official docs explains how you can benefir from reactive var.

2 Likes