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) {
...
});
}
Related
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
}
}
I have a template that subscribes to a document. Everything works fine in the DOM and Blaze updates as soon as an attribute used in the template helpers is changed.
I also have some custom logic that doesn't appears in the DOM and depends on the document attributes. How can I call a function to change that logic when an attribute is updated?
I'm looking for something like this.data.attr.onChanged where this would refer to the template and this.data is the data send to the template, as usual; or a Meteor function that is rerun on change where I could put my callback in.
I hoped that template.onRendered would be recalled, but that's not the case.
I've read a lot about reactive variables, but could not find how they could be useful here.
[edit] the change is coming from the server that is communicating with another service
I've tried Tracker.autorun like this:
Template.editItem.onRendered(function() {
var self = this;
Tracker.autorun(function () {
console.log("tracker", self.data.item.socketId);
});
});
And the corresponding route is:
Router.route('editItem', {
path: '/edit/:_id',
waitOn: function () {
var sub = Meteor.subscribe('item', this.params._id);
return [sub];
},
data: function () {
return {item: Items.findOne(this.params._id)};
},
action: function () {
if (this.ready())
this.render();
}
});
At some point, the property socketId gets removed from the corresponding document by the server and I'm sure of that since I've checked in the shell, but the tracker doesn't rerun.
Use Template.currentData().item.socketId instead of self.data.item.socketId, this will give you reactivity.
And in templates generally, use self.autorun instead of Tracker.autorun (unlike Tracker.autorun, this will ensure that the autorun is stopped when the template is destroyed). Likewise, if you want to subscribe in a template, use self.subscribe instead of Meteor.subscribe.
Code to see if Template.currentData() works for you:
Template.editItem.onRendered(function() {
var self = this;
self.autorun(function () {
console.log("tracker", Template.currentData().item.socketId);
});
});
I'm not sure if I got you right, you just want to observe your html inputs and apply the new value to your helper method(s) on change?!
If so, you could use session variables to store your temporary UI state:
// observe your input
Template.yourTemplate.events({
"change #inputA": function (event) {
if(event.target.value != "") {
Session.set("valueA", event.target.value);
}
}
}
// apply the changed value on your helper function
Template.yourTemplate.helpers({
getSomeData: function() {
var a = Session.get("valueA");
// do something with a ..
}
}
In meteor's official todo app tutorial this concept is also used.
If you need to re-run something which is not part of DOM/helper, you can use Tracker.autorun. According to meteor docs, Run a function now and rerun it later whenever its dependencies change.
here's the docs link
Try moving the subscription into Tracker.autorun
Template.editItem.onRendered(function() {
var self = this;
Tracker.autorun(function () {
Meteor.subscribe('item', this.params._id);
console.log("tracker", self.data.item.socketId);
});
});
Of course you can't use this.params there so you can store this as a Session variable
I just need some clarification on Meteor's default loading order.
I placed the following code
function isValid(str) {
return !/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g.test(str);
}
inside /lib/utils.js
and tried calling it from /client/views/userprofile.js
if (isValid(newUsername)) {
Meteor.call('editUsername', newUsername);
}
However, it says isValid is undefined. What's happening?
isValid is not a global function. Use isValid = function(){ [...] } instead of function isValid(){ [...] } to make it global.
I need to execute a jQuery function after a page loaded. The docs told me that it would be possible to hook into the 'PageLoaded' observer.
So I tried it like shown there. I put this function
Behaviour.register({
'#Form_ItemEditForm' : {
initialize : function() {
this.observeMethod('PageLoaded', this.pageLoaded);
this.observeMethod('BeforeSave', this.beforeSave);
this.pageLoaded(); // call pageload initially too.
},
pageLoaded : function() {
alert("You loaded a page");
},
beforeSave: function() {
alert("You clicked save");
}
}
});
into my cms.js which get's loaded in the backend. I tried it inside and outside (function($) { .. code ..}(jQuery)); and also inside the doucment.ready function inside the first function.
I always receive the same error in my console Uncaught ReferenceError: Behaviour is not defined.
Where is my mystake?
I believe you may have been looking at docs for 2.4, not 3.x
Version 3 and up are built using jQuery.entwine, where this from memory is old Prototype plugin stuff from 2.4, meaning of course that Behaviour is not defined, just as the error says.
The docs have recently been updated, so perhaps visit again, you might learn something new & much more helpful :)
I have the following:
function activate(routeData) {
// make dataservice call, evaluate results here. If condition is met, reroute:
if (true){
router.navigateTo("#/someRoute");
}
alert ("should not be shown");
}
The alert is getting hit however, and then the view changes.
How do I fully navigate away from the current item and prevent any further code in that vm from being hit?
Update:
I tried using guardroute but I have to activate the viewModel to call the dataservice that returns the data that determines whether or not I should re-route. Using guardroute totally prevents the dataservice from getting called (since nothing in the activate function will get hit).
I also tried returning from the if block but this still loads the view / viewAttached / etc so the UX is glitchy.
The following worked for me in Durandal 2.0:
canActivate: function() {
if(condition)
return {redirect: 'otherRoute'};
return true;
}
activate: // Do your stuff
It's mentioned in the documentation: http://durandaljs.com/documentation/Using-The-Router.html
Here's #EisenbergEffect answer to a quite similar discussion in google groups.
Implement canActivate on your view model. Return a promise of false,
then chain with a redirect.
You might want to give #JosepfGabriel's example (discussion) a try in Durandal 1.2. Check the correct router syntax for your Durandal version, you might have to substitute it with something like router.navigateTo("#/YourHash", 'replace').
canActivate: function () {
return system.defer(function (dfd) {
//if step 2 has a problem
dfd.resolve(false);
})
.promise()
.then(function () { router.navigate("wizard/step1", { trigger: true, replace: true }); });
}
However this is NOT working in Durandal 2.0 and there's a feature request https://github.com/BlueSpire/Durandal/issues/203 for it.
You can't call redirect into the active method.
You can override the guardRoute method from router, to implement redirections.
You can do somehting like that:
router.guardRoute= function(routeInfo, params, instance){
if(someConditios){
return '#/someRoute'
}
}
You can return a promise, true, false, the route to redirect... You can find more information about that in the next link: http://durandaljs.com/documentation/Router/
Rainer's answer was pretty good and works for me adding this small fix.
Inside the then() block simply call the navigation like this
setTimeout(function() { router.navigateTo('#/YOUR DESTINATION'); }, 200);
that should fix your problem. The setTimeout does the trick. Without it the newly navigated page catches the old NavigationCancel from the previous one.
Adding a return in your if (true) block should fix this.
function activate(routeData) {
if (true){
router.navigateTo("#/someRoute");
return;
}
alert ("should not be shown");
}