FB.XFBML.parse() fails during rendering - meteor

I've been trying to execute FB.XFBML.parse(); to reload all Facebook social plugins. I can successfully execute it in Template.sample.events({}) but not in Template.sample.onRendered() or Template.sample.rendered as I am getting an error saying that FB is undefined. My code is as follows:
Template.sample.onRendered(function() {
FB.XFBML.parse();
});
OR
Template.sample.rendered = function() {
FB.XFBML.parse();
}
How can I execute FB.XFBML.parse(); every time a template is loaded?

Just wrapped the method with a try-catch block. Noticed that for rendered is being called multiple times. The first pass fails saying FB is undefined while the succeeding passes succeeds.
Template.sample.rendered = function() {
try {
FB.XFBML.parse();
} catch (e) {
// Will normally crash but succeeding execution will be successful
}
}

Related

Can’t call View#subscribe from inside the destroyed callback

I got an error and strange behavior inside template.onDestoyed;
I have code for infinite scroll subscribtion (it stored in special subscribtion-template) It work fine, until i switch to another route, and create a new instance of subscriber-template.
Code:
Template.subscriber.onCreated(function() {
var template = this;
var skipCount = 0;
template.autorun(function(c) {
template.subscribe(template.data.name, skipCount, template.data.user);
var block = true;
$(window).scroll(function() {
if (($(window).scrollTop() + $(window).height()) >= ($(document).height()) && block) {
block = false;
skipCount = skipCount + template.data.count;
console.log(template.data);
console.log("skip_count is "+skipCount);
template.subscribe(template.data.name, skipCount, template.data.user, {
onReady: function() {
block = true;
},
onStop: function() {
console.log('route switched, subscribtion stopped');
}
});
}
});
})
});
When i "scroll down" on a page, subscriber work fine, when i go in another page and "scroll down" first i get a data from old subscriber template (what must be destroyed in theory) in first time. In second time (scroll down again) new instance of subscriber starts works normally.
PIRNT SCREEN CONSOLE
What i doing wrong?
Owch!
The good guy from meteor forums helped me.
Actually the problem is in jquery.scroll event. It not cleaned up when template is destroyed. (Is it a bug? Or it is normal behavior?). I just needed to unbind the scroll event in onDestroyed section.

Overriding Accounts.onEmailVerificationLink

Whenever I have Accounts.onEmailVerificationLink in clent side startup function, I get the following error message:
Accounts.onEmailVerificationLink was called more than once. Only one callback added will be executed.
What should I do to override this function correctly?
Accounts.onEmailVerificationLink should be called in top-level code, not inside Meteor.startup().
You can try this:
if (Meteor.isClient) {
Accounts.onEmailVerificationLink(function(token, done) {
...
});
}

Tracker.autorun() not executing jQuery functions

I am updating some Session variables with Router.onAfterAction whenever my route changes. Then I have a Tracker.autorun() waiting for a the change so it can run some logic and update some DOM classes. I checked the Sessions are set correctly and that the element to-be appended is targeted correctly. But my addClass() does not trigger. No console errors either. What am I missing?
Tracker.autorun(function (c) {
var colActive = Session.equals('navColumnActive', true);
var colVisible = Session.equals('navColumnVisible', true);
var $col = $("#nav-column");
console.log($col);
if (colActive) {
console.log("if triggered");
$col.addClass( "active" );
} else {
console.log("else triggered");
$col.removeClass("active");
}
if (colVisible) {
$col.addClass("visible");
} else {
$col.removeClass("visible");
}
});
I had the same problem just recently. In my case the reactive values triggering the computation where being executed before the DOM and the elements where properly rendered.
I would check if the session vars are being set after the DOM has been rendered. Therefore selectors like $col = $("#nav-column") came back empty, though perfectly worked when executed in the browser console.
You could try the following:
Template.<template_name>.onRendered(function() {
Session.set('navColumnActive', true);
Session.set('navColumnVisible', true);
})

Symfony JsFormValidatorBundle run validation on custom event

I am using JsFormValidatorBundle bundle and liked it very much. Validation works when submit is clicked but I want validation to work immediately after field change without submitting the form
I want to run validation on custom event as below:
$('form')
.find('input, select, textarea')
.change(function(){
$(this).jsFormValidator('validate');
})
.jsFormValidator({
showErrors: function(errors, sourceId) {
var list = $(this).next('span.help-block');
list.find('.' + sourceId).remove();
if(errors.length){
$(this).closest('div.mgnBtm20').addClass('badData');
$(this).closest('div.mgnBtm20').removeClass('goodData');
}else{
$(this).closest('div.mgnBtm20').removeClass('badData');
$(this).closest('div.mgnBtm20').addClass('goodData');
}
for (var i in errors) {
var li = $('<span></span>', {
'class': sourceId,
'text': errors[i]
});
list.append(li);
}
}
});
and I get this error: Uncaught TypeError: Cannot read property 'transformers' of undefined fp_js_validator.js:536
I tried to use exactly same code as in https://github.com/formapro/JsFormValidatorBundle/blob/master/Resources/doc/3_12.md but unfortunately get the same error

How to test Meteor router or Iron router with laika

I'm using laika for testing and the meteor-router package for routing. I want to do tests that navigate to some page, fill a form, submit it and check for a success message, but I'm stuck on the navigation part. This was my first attempt:
var assert = require('assert');
suite('Router', function() {
test('navigate', function(done, server, client) {
client.eval(function() {
Meteor.Router.to('test');
var title = $('h1').text();
emit('title', title);
})
.once('title', function(title) {
assert.equal(title, 'Test');
done();
});
});
});
This doesn't work because Meteor.Router.to doesn't have a callback and I don't know how to execute the next line when the new page is loaded.
I tried also with something like this
var page = require('webpage').create();
page.open('http://localhost:3000/test', function () {
...
}
but I got the error Error: Cannot find module 'webpage'
Edit
I'm moving to iron router, so any answer with that also will be helpful.
I had the same problem. I needed to navigate to some page before running my tests. I'm using iron router as well. I figured you can't just execute Router.go('foo') and that's it. You need to wait until the actual routing took place. Fortunately the router exposes a method Router.current() which is a reactive data source that will change as soon as your page is ready. So, in order to navigate to a specific route before running my tests, I firstly run the following code block:
// route to /some/path
client.evalSync(function() {
// react on route change
Deps.autorun(function() {
if (Router.current().path == '/some/path') {
emit('return');
this.stop();
}
});
Router.go('/some/path');
});
Since this is within an evalSync()everything that follows this block will be executed after the routing has finished.
Hope this helps.
Laika now includes a waitForDOM() function you can set up to wait for a specific DOM element to appear, which in this case would be an element in the page you're loading.
client.eval(function() {
Router.go( 'test' );
waitForDOM( 'h1', function() {
var title = $('h1').text();
emit( 'title', title );
});
});
The first parameter is a jQuery selector.

Resources