How to run a function in meteor reactively? - javascript

I have a function that does some gui-logic, and I need this to run every time meteor updates a template reactively.
I tried putting the code in the Template.myTemplate.helpers, like shown below, but then nothing works at all.
Template.ResourceManager.helpers({
names : function(){
myFunction();
return resources.findOne({age : 20}).names;
}
});
Basicly, I need myFunction() to run every time anything changes in resources. I can't find any way to do this. I've tried looking into autoRun, along with cursor.dependency, but I don't really understand how they work, or how to apply them here. Any help would be greatly appreciated! Thanks!

You can try using cursor.observeChanges on the resources collection.
function myFunction(id, fields){
console.log("something happened on resources", id);
}
var cursor = resources.find();
cursor.observeChanges({
added:myFunction,
changed:myFunction,
removed:myFunction
});
https://docs.meteor.com/#/full/observe_changes

Related

trying to attach a click event to an id that only fires once

UPDATE turns out the code is actually working see my answer below
I'm having some troubles here. I thought I found my answer in the .one method, but apparently, .one means ONLY ONCE PER PAGE PER ANYTHING EVER which isn't exactly what I was going for. Here's what my intention was:
$("#someID").one('mouseover', function() {
//do some stuff
});
$("#someOtherID").one('mouseover', function() {
//do some stuff
});
My expectation was that once that first one fired, that mouseover event would no longer fire for THAT ELEMENT.
The problem with this is that once the first one fires, the second one will not fire either. So the .one method appears to be disabling ALL mouseover events for ALL elements after that first one fires.
I did not expect this, I expected the .one to only apply to that first element. Is this just a flaw in my understanding of the .one method or am I coding wrong?
If it's just a flaw in my understanding, could someone point me in the right direction to correct my code?
Thank you in advance!
This is embarassing, I hope I don't get dinged for this and blocked again from stackoverflow (the easiest thing ever to get blocked from and the hardest to get unblocked).
First, #CertainPerformance, thanks for taking the time to look at my question. My real code didn't have the two mistakes you mentioned, I updated my post to reflect the correct syntax.
I'll be honest, my code is working now, and I have no idea why. I suspect I've been dealing with some crazy caching issues which frustrates me because I'm using inMotionHosting which has really great reviews, and I have caching disabled in cPanel.
If anything, maybe this thread will benefit somebody searching "how to make event fire only once in javascript".
You could make the callback run once like this:
// Extend the function prototype
Function.prototype.once = function() {
// Variables
var func = this, // Current function
result;
// Returns the function
return function() {
// If function is set
if(func) {
// Executes the function
result = func.apply(this, arguments);
// Unset the function, so it will not be called again
func = null;
}
// (:
return result;
};
};
// Bind the event to the function you will use as a callback
$("#someID").on('mouseover', function() {
console.log('just once');
}.once());

Subscribe function (event.currentTarget.activeElement.id) is blank

I am trying to call a subscribe function written by using publish. But the event captured has id blank. Following is my code
$.subscribe('onCmbNomineeSalutationComplete', function(event, data) {
onCmbNomineeSalutationChange(data, 'complete', event);
});
And I am trying to call it like this:
$(document).ready(function() {
$.publish('onCmbNomineeSalutationComplete');
});
The sub function gets called, but when I check it with debugger the event.currentTarget.activeElement.id is blank.
Kindly help me to identify what is going wrong here, and how I can get the id/name of the element by this method.
Also it would be of great help if someone could explain pub/sub in simple way.

How do I get the Yammer Embed Feed Event listeners to work?

From the documentation, all you need to hook onto a Yammer embed feed event is to use:
yam.on(eventId, callbackFunction, [context]);
Which I've done using the eventIDs they have supplied, so my code ends up looking like this:
<script type="text/javascript">
yam.connect.embedFeed({
container: "#embedded-comments",
network: "mynetwork",
feedType: "open-graph"
});
function alertMe() {
alert("Loading Completed!");
}
var nothing = "";
yam.on('/embed/feed/loadingCompleted', alertMe(), nothing);
</script>
Only that the alertMe() function gets called immediately, before the page has even loaded. Changing the eventID to something invalid shows the same behaviour, so I'm starting to think I'm missing something here.
Any ideas what could be causing the events to fire immediately?
Got it working by passing alertMe as a reference (removing the parentheses). I was seeing the events firing instantly due to them being executed as they were being read.
Quite a silly mistake, but being a javascript beginner I'm bound to make a lot of these :)
try this.
yam.on('/embed/feed/loadingCompleted', alertMe, nothing);

Prevent function from re-rendering template

Solved.
It turned out to be something else completely.
Thanks for everyone that tried to help, you guys rule!
I'll take a guess here but would need to see your code to make sure I'm giving you a good answer :-). You can't prevent a reactive data source from triggering an invalidation, but you can run some code in a nonreactive callback to make sure that code is NOT rerun.
Here are two examples to illustrate what's happening.
Template.myTemplate.helpers({
post: function () {
var someReactiveVar = Session.get('value');
return Posts.findOne({_id: 5});
}
});
In the above example, a change to post 5, or to Session's value will trigger the template to re-run. Let's say we want the template to re-run only for changes to the post, but not for the session variable. We could do this:
Template.myTemplate.helpers({
post: function () {
var someNonReactiveVar = Deps.nonreactive(function () { return Session.get('value'); });
return Post.findOne({_id: 5});
}
});
Now, just because we call Session.set('value', 'some other value') the template will not be re-run because we wrapped the get call inside a Deps.nonreactive callback.
Have you seen the answer to this question? Sounds like what you are looking for
Meteor.js - temporarily prevent a template from re-rendering (disable reactivity)

Why does this javascript work...but this doesn't?

I load everything on my page.
At the end, I have this script.
<script type="text/javascript">loadNewVideo('u1zgFlCw8Aw',0)</script>
It doesn't work.
But if I substitute it with this, it works.:
<input type="submit" onclick="loadNewVideo('u1zgFlCw8Aw',0);" >
In the .JS file, this is the function:
function loadNewVideo(id, startSeconds) {
alert('In-the-function');
if (ytplayer) {
alert('Found-ytplayer');
ytplayer.loadVideoById(id, parseInt(startSeconds));
}
}
Apparently, "ytplayer" is false in the first one!??
I don't know what ytplayer is, but I imagine this problem has something to do with the DOM not being fully loaded. Have you tried this?
<script type="text/javascript">
$(document).ready(function() {
loadNewVideo('u1zgFlCw8Aw', 0);
});
</script>
edit: If this doesn't work, you will have to give us more information. As Tim and Peter asked you in comments to your question, can you tell us where ytplayer is defined and what it is? I'm assuming it stands for YouTube Player, maybe it's being loaded/defined after you were calling loadNewVideo?
For example, if the code snippet above is above the part where ytplayer is defined in your document, this would still be called before ytplayer is loaded, depending on how you're loading it. As I said, please supply some more information.
I don't have an answer, but perhaps this will help you figure out when the ytplayer component is ready for use:
var startTimer = new Date().getTime();
function ytplayerReadyCheck() {
var ready = !!ytplayer;
if (!ready) {
window.setTimeout(ytplayerReadyCheck,50);
}
else {
var endTimer = new Date().getTime();
alert('ytplayer is now ready!\n\nWe waited '+(endTimer-startTimer)+' milliseconds for it');
loadNewVideo('u1zgFlCw8Aw', 0);
}
}
ytplayerReadyCheck();
Of course, this is scarcely replacement for figuring out where ytplayer is defined in the first place! Perhaps it's defined in a .js file that's dynamically loaded after the document has loaded?
I'd highly recommend getting hold of Firebug so you can more easily debug this kind of thing.
I would say this is because the DOM hasn't totally loaded at that stage. You want to hook the body onLoad event, or use jQuery to get the $(document).ready() hook.

Categories

Resources