How do I use UI.registerHelper in Meteor 0.8.0? - javascript

In 0.7.2, I could have something like this
<span>{{color 'blue'}}</span>
Handlebars.registerHelper('color', function (parameter) {
return Session.equals('color', parameter) ? 'blue' : 'red';
});
and it would work perfectly fine. What is the equivalent in the 0.8.0 release? I know they replaced Handlebars.registerHelper with UI.registerHelper, but this
UI.registerHelper('color', function (parameter) {
return Session.equals('color', parameter) ? 'blue' : 'red';
});
still returns this error
Exception in Meteor UI: Error: Can't call non-function: [object Object]
Any help?

Turns out it was all because one of my registerHelpers was the word 'parent'. Using that threw an error so it made it seem like all of my helpers were messed up. I'm guessing that it's a reserved word.

I'm doing this & it works (exactly as I use it). Do you use iron-router? This might do too.
UI.registerHelper('routeActive', function(routeName) {
var route = Router.current();
if(route && route.route && route.route.name == routeName) return 'active';
});
Then you can use the name of your template/route in routeName
I'm a bit unsure why you're getting that error are you sure its from the Handlebars expression.

You probably need to pass the parameter with a name:
<span>{{activePath path='home'}}</span>
UI.registerHelper('activePath', function() {
return Session.equals('activePath', this.path) ? 'active' : '';
});

Related

How to avoid the error Expected 1 argument but got 0 on Typescript

This is my JavaScript function
function movements(remove) {
var op = remove ? 'remove' : 'add';
crossvent[op](documentElement, 'selectstart', preventGrabbed); // IE8
crossvent[op](documentElement, 'click', preventGrabbed);
} function move(value) {
And this is how it's called
movements();
You can find reference for in jkanban.js file.
Now I have to change it to Typescript and I got this error on function calling,
Expected 1 arguments, but got 0
How can I resolve this problem in typescript ?
Simply add the question mark to the argument that requires your function, example:
function movements(remove?) {
// ...
}
You need to specify the input for calling movements().
You can set default to the variable using this:
function movements(remove = null) {
so that the function won't break even if you don't give it the input.
You can default it to anything you like though.

understanding the code from transit.js

I was just going through the source of transit.js and came across the following fucntion ::
$.cssHooks['transit:transform'] = {
// The getter returns a `Transform` object.
get: function(elem) {
return $(elem).data('transform') || new Transform();
},
// The setter accepts a `Transform` object or a string.
set: function(elem, v) {
var value = v;
if (!(value instanceof Transform)) {
value = new Transform(value);
}
// We've seen the 3D version of Scale() not work in Chrome when the
// element being scaled extends outside of the viewport. Thus, we're
// forcing Chrome to not use the 3d transforms as well. Not sure if
// translate is affectede, but not risking it. Detection code from
// http://davidwalsh.name/detecting-google-chrome-javascript
if (support.transform === 'WebkitTransform' && !isChrome) {
elem.style[support.transform] = value.toString(true);
} else {
elem.style[support.transform] = value.toString();
}
$(elem).data('transform', value);
}
};
I understand the latter part of the function, but its really hard to understand the initial part of the function, the function can be found on git too , HERE .
Initially I see this, $.cssHooks['transit:transform'] what is that line really saying?
After that we have the below line of code I.E. the getter and setter method,
set: function(elem, v) {
But who is passing the elem and v inside the function, I don't see anything being passed?
Read about cssHooks at jQuery cssHooks
Look at the source code (search for hooks.get and hooks.set)
.cssHooks is an array of objects that contains getter and setters tha will be executed by .css(). Thats all.
$.cssHooks['transit:transform'] = {set: function(elem,value){}, get: function(elem){}}
equal:
$.cssHooks['transit:transform'] = {};
$.cssHooks['transit:transform'].set = function(elem, value){};
$.cssHooks['transit:transform'].get = function(elem){};
$(element).css('transit:transform',value)
comes to:
$.cssHooks['transit:transform'].set(element,value)
$(element).css('transit:transform')
comes to:
$.cssHooks['transit:transform'].get(element)
$.cssHooks['transit:transform'] = {set:function(){}, get: function(){} }
{...} is an object creation.get and set not executed at this moment.
They created {set:function(){}, get: function(){} }
So. Simply: .css() will execute set and get functions for hooked property.
If you want to know how real getters and setters works:
Object.defineProperty()
In Javascript, you can add/access to a property with this syntax :
myObject.myProperty
or with this syntax :
myObject['myProperty']
This is the same result
So your line
$.cssHooks['transit:transform']
just mean that we want to store an object (code between {} in your original post) inside the 'transit:transform' property which is inside the cssHooks property which is inside the $ object
This is the same things :
$['cssHooks']['transit:transform']
The reason why they use the [''] syntax is that transit:transform contains the ':' char which is not allowed if you want to access it this way :
$.cssHooks.transit:transform //doesn't work
EDIT:
To answer to your second question, i don't know...the code you are showing is just the 'description' of the "transit:transform' property

Unable to pass string into a function?

My Javascript code is
function ad_cart(nm, mmi, pr) {
alert(imm);
}
The value i'm passing from onclick is this
onclick="ad_cart(Drafting Factory Folders ,2,3.50)"
But it is showing a error as
SyntaxError: missing ) after argument list
In mozilla
In chrome the error is
Uncaught SyntaxError: Unexpected identifier
But if i pass integer instead of string like
onclick="ad_cart(1,2,3.50)"
then it is working fine
Try like
onclick="ad_cart('Drafting Factory Folders' ,2,3.50);"
And your function will be like
function ad_cart(nm, mmi, pr) {
alert(mmi); // Instead of `imm`
}
function ad_cart(nm, mmi, pr) {
alert(imm);
}
Seems to spell mistake also, getting mmi and showing imm
And the string should be wrap by ''
edit:
function ad_cart(nm, mmi, pr) {
alert(mmi);
}
ad_cart('string' ,number,number)

Jquery cannot call method replace of undefined

I'm not sure why im getting the error, but i'm getting "cannot call method replace of undefined". It's happening on the the $('#wizard'+optionalArg) part, if I remove the optionalArg part it works fine. Any idea why this is happening?
function loadWizard(optionalArg)
{
optionalArg = (typeof optionalArg === "undefined") ? "" : optionalArg;
$('#wizard'+optionalArg).smartWizard({contentURL:'/welcome/form_view',
transitionEffect:'slideleft', onLeaveStep:leaveAStepCallback,onFinish:onFinishCallback, contentCache:false});
}
function call
var id = 2;
loadWizard(id);
before I send over the ID i run this
$('#all_wizards').append('<form action="#" method="POST"><div id="wizard2" class="swMain template"></div></form>');
so wizard2 should exist..
It can be:
$('#wizard'+optionalArg) //would make wizard2
there is no element in your html with this id, so calling method on undefine throw exception.
Try with null check:
function loadWizard(optionalArg)
{
var myElement=$('#wizard'+optionalArg);
if(myElement.length>0){
$('#wizard'+optionalArg).smartWizard({contentURL:'/welcome/form_view',transitionEffect:'slideleft', onLeaveStep:leaveAStepCallback,onFinish:onFinishCallback, contentCache:false});
}
}
Are you sure you have an element with
id="wizard1" (assuming optionalArg = 1)
Debug by putting a console.log to ('#wizard'+ optionalArg) and check whether the element exists? most likely the element does not exists and hence creating and error.

arbitrary method names in javascript object

I'm learning more about javascript OOP by rolling my own console.log variant with some extra features I want.
So far I have
debug = {
consoleAvailable : (typeof console == "object"),
reportToConsole : 0,
list : [],
setReporting : function(level){
this.reportToConsole = level;
return true;
},
log : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments);
this.list.push({'type':'log', 'msg':this.log.arguments});
return true;
},
};
This is all working nicely, but I don't want to have to list all of the log,error,warning etc functions. Instead I would like to be able to just type debug.[something] and for a function to interpret that [something] and execute it in the same way as I have the log function working.
Is this even possible? If so how do I go about it?
Here is some examples of what I would like to be able to do.
debug.setReporting(1); //yes, I want to print to console
debug.log('foo', 'bar', 'baz'); //arbitrary number of arguments (this is already working)
debug.error('qux'); //function I haven't named, but there is a console.error function
debug.arbitraryName([1, 2, 3]); //no function for console.arbitraryName (ideally it would just console.log the argument(s)
Edit
Ok, it looks like #Rob W's method is the way to go, however I am having trouble implementing. It seems that I am not passing the name of the function correctly or similar. I have a fiddle here showing the problem http://jsfiddle.net/xiphiaz/mxF4m/
Conclusion
It looks like there is too many browser quirks to get a truly generic debugger without writing browser specific code, so instead I have just listed my most used log functions (log, warning and error). This does give me the option to further customize result of each of these functions.
result:
debug = {
consoleAvailable : (typeof console == "object"),
reportToConsole : 0,
list : [],
setReporting : function(level){
this.reportToConsole = level;
return true;
},
log : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments);
this.list.push({type:'log', msg:this.log.arguments});
return true;
},
warn : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.warn=="function") console.warn.apply(console, this.warn.arguments);
this.list.push({type:'warn', msg:this.warn.arguments});
return true;
},
error : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.error=="function") console.error.apply(console, this.error.arguments);
this.list.push({type:'error', msg:this.error.arguments});
return true;
}
};
debug.setReporting(1);
debug.log('foo', 'bar', 'baz');
debug.error('qux');
debug.warn({test:"warning"});
console.log(debug.list);
You can get an array of all properties (including non-enumerable ones) using the Object.getOwnProprtyNames method. Then, enumerate through it, and check whether the console[key] is a function. If yes, extend your own object with the method.
Object.getOwnPropertyNames(console)
As for your last quesion, there's a non-standard __noSuchMethod__ method which intercepts calls to undefined functions.
I strongly recommend to use my first proposed method, because the console method will not magically grow bigger. It also makes debugging easier.

Categories