Hi there!
I’m trying to make a reactive global helper but I’m getting an error. The error reads Exception in queued task: TypeError: Cannot read property 'splice' of null
.
I adapted an existing helper by following an example on the homepage of the Blaze documentation (first example.) I also referenced the UI.registerHelper section but I still seem to be doing something wrong.
var currentTime = new Blaze.Var(0);
UI.registerHelper('humanizedTime', function(timeOfEvent) {
var diff = moment(timeOfEvent).diff(currentTime.get(), 'minutes');
var hours = diff / 60;
var days = hours / 24;
var weeks = days / 7;
if (weeks <= -2) {
return moment(timeOfEvent).format('dddd, MMMM D, h:mm A');
} else if (days <= -1) {
return moment.duration(days, "days").humanize(true);
} else if (hours <= -1) {
return moment.duration(hours, "hours").humanize(true);
} else {
return moment.duration(diff, "minutes").humanize(true);
}
});
setInterval(function () {
currentTime.set(new Date());
}, 1000);
(And please feel free to make any and all proposals for improving this function.)
var currentTime = new Blaze.Var(new Date());
Exception from Tracker recompute function: Error: No such function: humanizedTime
Any idea?
You’re not trying to evaluate humaziedTime(<someTime>)
in your JavaScript code, right? humanizedTime
can only be used in Spacebars.
That’s correct. It only appears in one template as <h4>{{humanizedTime etoeventSubmitted}}</h4>
and the declaration.
edit: I really should have included the whole error. The following is said to be coming from debug.js:41
. WebStorm is highlighting .Var()
as being Unresolved type Var
.
I’m also running Meteor on Windows.
Exception from Tracker recompute function: Error: No such function: humanizedTime
at Blaze.View.lookup (http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:2889:15)
at Spacebars.call (http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:172:18)
at Spacebars.mustacheImpl (http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:109:25)
at Object.Spacebars.mustache (http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:113:39)
at null._render (http://localhost:3000/client/etoevents/template.etoeventItem.js?ba66cbb537e13d4c98119fc51d3805ebcd7386ba:52:22)
at doRender (http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:1928:25)
at http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:1821:18
at Function.Template._withTemplateInstanceFunc (http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:3383:12)
at http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:1820:29
at Object.Blaze._withCurrentView (http://localhost:3000/packages/blaze.js?b0fa84e3d7a352d325a81441bf2b6dd19cb7e554:2105:12)
If I read this code right, you haven’t registered any (global) helper named humanizedTime
. Are you sure the call to UI.registerHelper
is executed before the helper is used?
Are you using the Meteor platform or the Blaze standalone project?
I need a badge that says, “I don’t know what I’m doing.”
I didn’t realize Blaze had a standalone project. But those are the docs I linked to in my original post so I guess I’m referencing the wrong docs? 
Also, I thought [Template|UI].registerHelper
was registering the helper globally, no?
I don’t know if this is executed before or after it’s being used. I was letting Meteor handle that. Part of the reason for this is because I don’t have a problem with this helper when it’s used normally (without the reactivity.) Normally it looks like this:
Template.registerHelper('humanizedTime', function(timeOfEvent) {
var diff = moment(timeOfEvent).diff(new Date(), 'minutes');
var hours = diff / 60;
var days = hours / 24;
var weeks = days / 7;
if (weeks <= -2) {
return moment(timeOfEvent).format('dddd, MMMM D, h:mm A');
} else if (days <= -1) {
return moment.duration(days, "days").humanize(true);
} else if (hours <= -1) {
return moment.duration(hours, "hours").humanize(true);
} else {
return moment.duration(diff, "minutes").humanize(true);
}
});
Yea, if you use the Meteor platform, you should read the docs at http://docs.meteor.com/#/full/ instead, and you should use Template.registerHelper
instead of UI.registerHelper
.
It is not correct. Just look at lookup.js from blaze package
Blaze._globalHelpers = {};
// Documented as Template.registerHelper.
// This definition also provides back-compat for `UI.registerHelper`.
Blaze.registerHelper = function (name, func) {
Blaze._globalHelpers[name] = func;
};
UI.registerHelper and Template.registerHelper are both Blaze.registerHelper
I guess that error could be the meteor-win-only issue
My point was that one should use Template.registerHelper
in favor of UI.registerHelper
on the Meteor platform.
I doubt this is a Windows related problem. The helper is registered on the client in the browser, which should be OS independent, but I don’t know.
@Giraffeslacks, can you share your code with us (GitHub?)?
I get the same result in both cases.
I appreciate your offer to help further but I’m afraid I can’t.
I’ll see if I can’t use another method to make this reactive and I’ll stick with using the standard docs as a reference.
I don’t see any Blaze.Var
in the docs (Maybe you mean Blaze.ReactiveVar
, even then, just use reactive-var
package / ReactiveVar
),
You could also cut out the middle-man and just use the tracker
package. eg:
var timeDep = new Tracker.Dependency;
UI.registerHelper('humanizedTime', function(timeOfEvent) {
timeDep.depend();
var diff = moment(timeOfEvent).diff(new Date, 'minutes');
var hours = diff / 60;
var days = hours / 24;
var weeks = days / 7;
if (weeks <= -2) {
return moment(timeOfEvent).format('dddd, MMMM D, h:mm A');
} else if (days <= -1) {
return moment.duration(days, "days").humanize(true);
} else if (hours <= -1) {
return moment.duration(hours, "hours").humanize(true);
} else {
return moment.duration(diff, "minutes").humanize(true);
}
});
setInterval(function () {
timeDep.changed();
}, 1000);
2 Likes
Hi @nathan_muir,
Thanks for your response. It worked! With a little help from http://docs.meteor.com/#/full/tracker.
I linked to the docs I was referencing in my original post: http://meteor.github.io/blaze/. Right on the homepage there it says var counter = new Blaze.Var(0);
.
I had to make some changes to get it to work but that wasn’t too much trouble. The docs provided a straightforward example.
var currentTime = new Date();
var currentTimeDep = new Tracker.Dependency;
Template.registerHelper('humanizedTime', function(timeOfEvent) {
currentTimeDep.depend();
var diff = moment(timeOfEvent).diff(currentTime, 'minutes');
var hours = diff / 60;
var days = hours / 24;
var weeks = days / 7;
if (weeks <= -2) {
return moment(timeOfEvent).format('dddd, MMMM D, h:mm A');
} else if (days <= -1) {
return moment.duration(days, "days").humanize(true);
} else if (hours <= -1) {
return moment.duration(hours, "hours").humanize(true);
} else {
return moment.duration(diff, "minutes").humanize(true);
}
});
setInterval(function() {
currentTime = new Date();
currentTimeDep.changed();
}, 1000);
Great that the problem has been solved, but I’m really curious why the working solution works. On the Meteor Platform, Blaze.ReactiveVar
is the same as ReactiveVar
(if the reactive-var
package has been added), and under the hood ReactiveVar
uses Tracker.Dependency
. I don’t see what difference it makes, anyone who knows?
@Peppe_LG The issue is that the original code uses Blaze.Var
instead of Blaze.ReactiveVar
.
I only suggested using a Tracker.Dependency
instead of a var - however the solution by @Giraffeslacks somewhat defeats the point by storing a currentTime
variable. (Which is effectively what a ReactiveVar
would do).
eg. Is your abstraction “Invalidate this computation regularly” or, “time as a reactive data source”.
Thanks @nathan_muir, I missed he was using Blaze.Var
^^’ That explains everything, although @Giraffeslacks could have mention the undefined is not a function
error he probably was getting 
@Peppe_LG That’s kind of an unnecessary thing to say. I provided to the forum the code I was using and I provided the errors as well.
edit: I stand corrected. I did in fact miss the undefined is not a function
error.
If you want a good example go there: