Meteor helper doesn't refresh on Reactive var .set() - meteor

I update reactive var on autorun. The same reactive var is used in helper. But helper values doesn't refresh by autorun function. My below code will explain you clearly.
Template.home.onCreated(function () {
var self = this;
self.ITEMS_INCREMENT = 2;
self.itemsLimit = new ReactiveVar(2);
});
Template.home.onRendered(function () {
var self = this;
this.autorun(function(){
if( true ){
self.itemsLimit.set(self.itemsLimit.get()+self.ITEMS_INCREMENT);
console.log(self.itemsLimit.get()); // set values are fine
}
});
});
Template.home.helpers({
testHelper: function(){
console.log(Template.instance().itemsLimit.get()); // console returns 2 and 4 only. no more update :(
return true;
}
});
Anything wrong in handling of data or usage? How to make helpers are workable?

Well well well, I don't see where are you going to change the value of reactive variable. It gets changed only ones, when first computation runs in your tracker. So only ones you see the update. The idea of using ReactiveVar is that when you change it, it gets changed inside helper or inside autorun.
Briefly, what you can do to test it is:
Template.home.onRendered(function () {
var self = this;
Meteor.setInterval(function(){
self.itemsLimit.set(self.itemsLimit.get()+self.ITEMS_INCREMENT);
}, 500);
});

Related

How to use findOne in Template onCreated and access it in helper

Here is my template onCreated and helper function. I have provided inline comments to add some clarity. I can see that self.post is eventually set because it shows up on my console when I log Template.instance(). However, when I log Template.instance().post, it is always undefined.
Template.default.onCreated(function() {
var self = this;
self.autorun(function() {
var postId = FlowRouter.getParam('post_id');
self.subscribe('onePost', postId);
self.post = Posts.findOne(FlowRouter.getParam('post_id'));
});
});
Template.default.helpers({
poststage: function(stage) {
console.log(Template.instance()); // I can see post object here
console.log(Template.instance().post; //always undefined
if(Template.instance().post) {
// never true
return Template.instance().post.stage == stage;
}
}
});
Template.default.events({
'submit form':function(event, instance) {
Meteor.call('someFunc', instance.post.anotherField);
}
});
Edit: I should add, I'm trying to avoid writing the query twice because I'm also using it in the Template events. (see code).
This feels like a timing issue. You are subscribing to the onePost publication but you aren't waiting for that subscription to be .ready() before assigning self.post The autorun also seems superfluous. You shouldn't need to rerun that block of code in the onCreated block. I suggest:
Template.default.onCreated(function() {
this.postId = FlowRouter.getParam('post_id');
self.subscription = subscribe('onePost', this.postId);
});
Template.default.helpers({
poststage: function(stage) {
if ( this.subscription.ready() ){
return Posts.findOne(this.postId).stage;
}
}
});

Accessing Elements on electron webview using spectron

I am trying to automate a electron app which loads its content on to an webview. I am using spectron and webdriverio for it.
here is the code i am using.
it('should assess webview', function() {
var self = this;
return this.app.client.waitUntilWindowLoaded()
.windowHandles().then(function(session) {
self.app.client.switchTab(session.value[1])
.click("#my-id")
.then(console.log.bind(console))
.catch(console.log.bind(console));
});
});
This doesn't seem to work. i am not sure where i am going wrong. But i used
it('should assess webview', function() {
var self = this;
return this.app.client.waitUntilWindowLoaded()
.windowHandles().then(function(session) {
self.app.client.switchTab(session.value[1])
.getSource()
.then(console.log.bind(console))
.catch(console.log.bind(console));
});
});
the above code to ensure whether the webview window handle is correct. And it is. Kindly help. Thanks
I have checked the code, using spectron and running webview inside simulating this behaviour, your code works fine. Re-written the codes. Hope this helps.
it('should assess webview', function() {
var self = this;
return this.app.client.waitUntilWindowLoaded()
.windowHandles().then(function(session) {
// Need to return the promise back, if promise is
// it would wait for the state or else app will exit.
return self.app.client.switchTab(session.value[1])
.click("#my-id") // check whether selector is present in DOM
.then(console.log.bind(console))
.catch(console.log.bind(console));
});
});
or
it('should assess webview', function() {
var self = this;
return this.app.client.waitUntilWindowLoaded()
.windowHandles()
.then(function(session) {
// switchTab & window will both focus
// window or tab which is active
return this.window(session.value[1])
})
.click("#my-id") // check whether selector is present in DOM
.then(console.log.bind(console))
.catch(console.log.bind(console));;
});

Meteor - onCreated collection lookup

I'm stumped here. I can't get it to find a collection from the onCreated method. If I log the data.source_id right before the call and then do the same lookup in the console, it finds it. Is there something special about onCreated or something? Am I just doing it wrong?
client/setup.js
Meteor.subscribe('source_elements');
Meteor.subscribe('internal_elements');
client/submit.js
Router.route('/element/submit', function() {
this.render('submit', {
data: {
source_id: this.params.query.source_id,
},
});
});
Template.submit.onCreated(function() {
var data = Template.instance().data;
var source_element = SourceElements.findOne({'_id': data.source_id});
console.log(source_element); // EMPTY!!
});
Template.submit.helpers({
element: function() {
var data = Template.instance().data;
var source_element = SourceElements.findOne({'_id': data.source_id});
console.log(source_element); // RESULT!!
return source_element;
},
});
Subscriptions are asynchronous. It looks like you are creating the template before the data has arrived at the client. By the time you execute the find in the console, the client has received the data.
Inside your onCreated function, you could use Tracker.autorun to specify a function that will be rerun when the SourceElements collection changes (that's what all template helpers do behind the scenes):
Tracker.autorun(function() {
var element = SourceElements.findOne({'_id': data.source_id});
console.log(element);
});
This function will be called immediately. At this point, findOne will probably return undefined because the subscription is not ready yet. Once the data has arrived, the function will be called again and you can process the returned elements.

In Meteor, how to set a reactive dependency on a subpart of a template data context?

Consider the following code :
Template.fullDoc.rendered = function() {
// Get triggered whenever the selected document id changes
this.autorun(function() {
var docId = isolateValue(function() {
return Template.currentData().selectedDoc._id;
});
...
});
}
This code doesn't work. Inside isolateValue(), Template.currentData() sometimes triggers an exception: Exception from Tracker recompute function: Error: There is no current view (this corresponds to the fact that Template.instance() returns null).
So how do you set a reactive dependency on a subpart of a template data context?
You could recreate the isolateValue behaviour in a way which doesn't cause Template.instance() to get set to null sometimes.
$ meteor add reactive-var
Template.fullDoc.rendered = function () {
var docIdVar = new ReactiveVar();
this.autorun(function () {
docIdVar.set(Template.currentData().selectedDoc._id);
});
this.autorun(function () {
var docId = docIdVar.get();
// ...
});
}
This makes use of the fact that setting a ReactiveVar to the same value it already has will not trigger an invalidation. (By default this only works for primitives; for objects you'll need to pass a custom equalsFunc when you construct the ReactiveVar. If _id is a string, you're fine. If it's ObjectID you probably aren't.)

Implement added, changed and removed server side

Context : I am using a Collection Params to call method from the Server to a C app. The C app does its stuff and then calls the server by RPC to send me the results. With the result, I get the Params ID to delete the corresponding element.
With the deletion of the Element of Params, the C app gets a removed message. I want to prevent this behavior to avoid overloading the C app of messages.
I've thinked about implementing the removed event into the Publish method on the server to prevent the server from informing the C app. I just want the C app to be inform about added events.
On the Meteor Doc, there is an example of implementation of added and removed but I don't understand it. Can someone help me ?
I've tried this (don't work at all) :
Meteor.publish('expert_mode_parameters', function ()
{
var self = this;
var handle = Expert_Mode_Parameters.find().observeChanges({
added: function ()
{
return Expert_Mode_Parameters.find();
},
removed: function ()
{
return [];
}
});
self.ready();
self.onStop(function () {
handle.stop();
});
}
It looks like your goal is to subscribe to a data set but only receive added messages, not changed or removed.
The below code should do this:
Meteor.publish('expert_mode_parameters', function () {
var self = this;
var handle = Expert_Mode_Parameters.find().observe({
added: function (document) {
self.added("expert_mode_parameters", document._id, document);
}
});
self.ready();
self.onStop(function () {
handle.stop();
});
}
The concept is, you're watching the results of Expert_Mode_Parameters.find() and then calling self.added(document) when there is a new item. The same thing can easily be expanded to include changed.

Resources