[SOLVED] Template.currentData() not reactive? Other ways of modifying template data context?


#1

I know that Template.instance().data is not reactive, but currentData() seems reactive

Establishes a reactive dependency on the result.

However, doing this from an event handler:

Template.currentData().foo = 'Hi'

doesn’t update the template.

My actual problem is I want to modify the state of the parent template through a event handler, what are my options? I know I can do this using Session and helpers. Any other ways?


Accessing siblings template context to grab UI's data
#2

Seems like you want Reactive Variables.


#3

Thanks sacha, it looked like a good idea, but when I started looking into it, it seems i’ll hit the same problem as this guy:


also, i’m concerned that a HCR will wipe the instance out, bit of an edge case, but not a nice behaviour from the user’s pov.
So I think I’ll stick with Session for the moment and code around the globalness of Session.
For anyone else learning reactiveVar, there’s a nice article on it.


#4

You can declare you reactive var in the root level of scope. Just write in you .js file something like this:

var window = this
window._myReactiveVar = new ReactiveVar('')

and now you can get access to this variable in any place in current file through window._myReactiveVar
If you need to get access to this variable in another .js file, then do the same declaration
var window = this
Or you can declare this variable only for file scope. Just skip the window declaration

var myVar = new ReactiveVar('')

But maybe you should use Session instead.


#5

Or you can declare the reactive variable on the parent template instance (probably in the onCreated event of the parent) and access it in the child using this.parent().reactiveVar or Template.instance().parent().reactiveVar (depending if you are in onCreated/onRendered or in a helper/event handler, respectively).


#6

@dominis yeah in this case, the var would be global but without HCR support. I don’t want my users to lose data they’re working on when I do a publish. It seems I have to keep most of my client data in Session.

@veered the reason why I don’t like the parent template instance solution is because it breaks the moment i go to refactor the template into two (Template.instance().parent().parent()…reactiveVar). Having arbitrary levels of parents to reference is just bad. Angularjs also had that with their scopes and I got away with it from mostly storing states in services. Plus we’ve still got the issue the data should be recovered on HCR.


#7

A named reactive dictionary is preserved across HCR. However, I think that critical information should be stored in Mongo, not as reactive variables.


#8

I’m agree with @veered, important data should be saved not into reactive var/session/etc. If you don’t want save unready data into the mongo - save it to the localStorage. If you worry about HCR, you also should worry about some unexpected behavior like user close the tab in browser, refresh page by some reason, etc. Any js storages will be cleared in this cases.


#9

Offtopic reaction:

Well, being reactive variable and being able to be rewritten anywhere can be different.

I was deep in iron router documentation and you can define reactive variables in controllers too and access them and access controller methods.
So mby it is possible to change route state by calling router controller methods and just listen for changes on these “reactive” variables in current.param etc

http://iron-meteor.github.io/iron-router/#accessing-the-current-route-controller


#10

Still I kinda like the way how they used global reactive dir to index various components in this article/package.


#11

I wouldn’t recommend defining state that needs to be persistent across routes in Route Controllers. Route Controllers are torn down between routes. I think that your best bet is either storing the info in Mongo or defining a global App = {} namespace and storing your reactive variables there.


#12

Good reads there @shock, I’m getting the gist that using reactiveVars/Dicts are the way to go for purely UI based states and mongo is the way to go for even partially saved content that needs to persist across unpredictable user actions, HCR just being one of many considerations. Thanks for reminding me of browser refreshes again @dominis :smile:

Now that I think about it more, I’ll use both a named ReactiveDict and Mongo. I want to load up a user’s previous preferences (set on completing a form) but allow them to change these per instance of a route. So storing preferences in mongo and when a route/template is hit I’ll either use iron router state or template.onCreate to pull the preferences out and use it to control the UI for that particular page instance.


#13

Accessing parentData(1) may be not possible due to a “bug” in meteor spacebars compiler. I created some working example here

http://meteorpad.com/pad/xSYbj5cpx4GxC3ExR/Leaderboard_Template_parentData_Bug_Example

and made a PR to solve this in upcoming releases