we use ReactiveMethod calls inside helpers in meteor.But most of the time without refreshing the browser it show the previous data(if the passed parameters are not changed). What is the solution for this?
inside helpers I use below method
customerOutsTanding: function(){
return ReactiveMethod.call("outstanding",customerId);
}
outstanding will pay using boostrap model input text and it will close.But using reactive method calling it will not update.after refreshing the browser it will get update
ReactiveMethod.call is only called again when the parameters changes. In your case parameter iscustomerId which is not getting changed since its not a reactive data source.
You probably need to use Tracker.Dependency (https://docs.meteor.com/api/tracker.html#tracker_dependency) to reactively trigger this function again. Something like this
var outstandingDep = new Tracker.Dependency;
customerOutsTanding: function(){
outstandingDep.depend();
return ReactiveMethod.call("outstanding",customerId);
}
Then when you want to change the dependency which is not clear from the question you need to call outstandingDep.changed() may be you need to call when the input text changes.
Related
Is it a good practice to make DOM changes from Meteor helpers? I'm currently relying on a javascript function to run inside the Meteor helper which makes the function run every time a collection data change occurs.
I know there is Tracker.autorun() but as far as I know, Tracker.autorun() only works for Session variables and does not work for collection data changes.
My current ways so far has not failed me or caused any problems but I'm not 100% sure if this was how Meteor was meant to be used.
Code Example
Template.page_body.helpers({
orange: function() {
do_some_rand_function()
return this.name
}
})
This code will make sure that do_some_rand_function() is ran every time this.name changes (this.name is a variable gotten from a Mongo Collection, therefore it is reactive).
No. Helpers should not have side effects (such as manually updating your DOM, modifying the database, making an HTTP request, etc.).
Your description sounds like a good use case for adding a template autorun in the rendered callback. All autoruns are reactive computations so they will rerun if any reactive variable used within them changes (Session, Meteor.user, Collections, etc.).
Give something like this a try:
Template.myTemplate.onRendered(function() {
this.autorun(function() {
if (MyCollection.findOne()) {
do_some_rand_function();
}
});
});
Also note that template autoruns are automatically stopped when the template is destroyed.
This is a general question about designing meteor applications or debugging meteor applications.
When I write meteor applications, I usually update session variable values to trigger re-runing a template helper function and/or re-rendering a template. So my application has quite a few different session variables.
Sometimes I find that the helper function gets re-run multiple times, but I can't think of any reason why it re-runs so many times. It must be some session variable gets updated and causes the re-run. Is there a way to figure out which session variable causes it?
The general question is: in a reactive design, when I see a template gets re-rendered, how to find why it gets re-rendered?
You could use Deps.autorun to quickly figure out which it is, If you're looking to debug its a quick a gritty way to do
Drop in the code like
Deps.autorun(function() {
Session.get("something");
console.log("Session something has changed");
});
Deps.autorun(function() {
Meteor.user()
console.log("Meteor user has changed");
});
You can place blocks of code like this on your client side to see which is changing. Each one will run once, initially, then after for each time the reactive variable inside it changes.
You would have to do this for each variable you use in your template and it would help you find out which is changing, each Deps.autorun block will run independently only when the variable inside it changes.
I'm trying to wrap my head around Meteor's way of dealing with reactivity and I want to make sure I've got some concepts right.
Take the follow reactivity example:
A user types something into a form field. The thing that he is typing is instantly displayed somewhere else on the page, as the user is typing, letter by letter. An instantaneous duplication.
From what I know about Angular, this is a very common example of reactivity. Angular binds the input directly to the output on the client side. There's nothing in between.
Correct me since I could be wrong, but Meteor can do this, but the input would first need to be captured and stored into a Mongo + MiniMongo DB (perhaps only as a collection in local storage), there would need to be a subscribe step, and those values would then be read and displayed on the page.
Is there a way to directly bind an event on the front end to another thing on the front end like Angular does?
Is this right? For Meteor to have the front-end-only reactivity of Angular it must first go through the intermediary of a collection, meaning extra code would be necessary to accomplish this compared to Angular?
The example in the Meteor Docs:
Deps.autorun(function () {
Meteor.subscribe("messages", Session.get("currentRoomId"));
});
So here, when the data of currentRoomId changes, the function is reactive to that data change and the function runs (in this case Meteor subscribes to messages).
Using Session variables is the only way I see of possibly binding two parts of a view together directly. Are there other ways?
Meteor's client-side reactivity system (Deps) is not coupled with its live MongoDB syncing. You can use it with any reactive data source which implements the right interface, including data sources which are entirely client-side. For example, you can use the built-in Session object. This is just a client-side key-value store with support for Meteor's reactivity, and you don't have to do any publish or subscribe to use it.
This standard way to do this sort of thing looks something like this:
<input id="field" value="{{fieldValue}}">
Template.form.fieldValue = function () {
return Session.get("fieldValue");
};
Template.form.events({
"input #field": function (evt) {
Session.set("fieldValue", $(evt.currentTarget).val());
}
});
Now the Session variable fieldValue is synced up to the form field. You can call Session.get("fieldValue") in some helper and that template will re-render when the user types in the form field. And if you call Session.set("fieldValue", "blah") then the form field will update itself.
As for your edit: You can make your own reactive data sources using Deps.Dependency, or you could meteor add reactive-dict although that's not documented. There may be packages on Atmosphere.
I'm looking to make an element flash on screen when the underlying collection is updated.
It seems to me that it would make to have an equivalent of Template.my_template.rendered = function(){} which is fired every time the template is updated.
Ideally, this function would not fire the first time the template is rendered.
This is seems like such an obvious use case, am I missing something?
For Meteor < 0.8
You should use Template.myTemplate.created to do something for the very first time. From the docs Template.myTemplate.rendered is fired everytime there is a change including the first time. If you want to limit it to only the second time and changes after that (I'm guessing this is what you want), you have to write some custom logic. Currently there is no Meteor api that supports that.
For Meteor-0.8
It seems like this API underwent some backwards incompatible changes in Meteor-0.8.
There is an elegant way to achieve this as described Adaptation to the new Meteor rendered callback here. Bascially you should modify whatever function you are attaching to the variables inside your Template's javascript by calling a helper function once. For example,
var renderCount = 1;
var myHelper = function () {
console.log("rendered #" + renderCount);
renderCount++;
};
Template.myTemplate.myVariable = function () {
myHelper();
return this.name;
};
Hope this helps. There is also another alternative approach in that same repo. You might like that one.
There is no simple solution; more discussion here: https://groups.google.com/forum/#!topic/meteor-talk/iQ37mTP3hLg
Could someone clarify how Meteor (Handlebars) templates interact with reactive sources? There is already a lot in the documentation but a more systematic explanation would help.
For instance, it seems the following does not trigger a template re-draw when the Session variable is changed
Template.foo.rendered = function () {
var selectedItem = Session.get('item_selected');
... do stuff ...
}
I don't understand why the Template.rendered event does not react to reactive source changes. I would also like to understand if other events/methods exhibit this special behavior.
The template will re-render when you set the item_selected value with
Session.set("item_selected","value");
This Session hash, beside the name has a reactive dependency similar to Deps.depends. When you change this Session hash the current reactive context will be invalidated and everything will be redrawn/re-rendered (which is called via Session.set).
The .rendered method will then be run where you can use this new value like you do with var selectedItem
For a very detailed videocast on how exactly it works you can have a look at the videos on EventedMind which demonstrate how Session is built and how to make another variable reactive.
http://www.eventedmind.com/posts/meteor-the-reactive-session-object
http://www.eventedmind.com/posts/meteor-introducing-deps