As I looked through the source code of the find() of mongoose.js, which looks like following:
Query.prototype.find = function(conditions, callback) {
if (typeof conditions === 'function') {
callback = conditions;
conditions = {};
}
conditions = utils.toObject(conditions);
if (mquery.canMerge(conditions)) {
this.merge(conditions);
}
prepareDiscriminatorCriteria(this);
try {
this.cast(this.model);
this._castError = null;
} catch (err) {
this._castError = err;
}
// if we don't have a callback, then just return the query object
if (!callback) {
return Query.base.find.call(this);
}
this._find(callback);
return this;
};
I really don't understand the part
this._find(callback);
what this means? what is the _find in javascript?
Thanks in advance!
Max
what “this._find(callback)” means in Mongoose find() method?
It's a function call. It seems this._find is a supposed to be a function. That function is called and passed the value of callback.
what is the _find in javascript?
Nothing special. It's simply a property with name _find. If you continue looking through the source code, you might discover its definition somewhere.
Related
Consider this
var obj = {
process: function run(param) {
return;
}
}
and
runSomething(param);
The situation is that the run function is built elsewhere in the application and contains some additional processing that need to be done to the runSomething response.
is it possible to somehow run obj.run and insert the runSomething into it, so that runSomething can use the param that was passed in as obj.run("something")
Producing the same result as
var obj = {
process: function run(param) {
return runSomething(param);
}
}
you can do this
var obj = {
process: function run(funct, param) {
return funct(param);
}
}
obj.process(runSomething, param);
I'm using redis using node (node_redis module) and am trying to wrap my retrieval code for debugging and DRY, and having trouble understanding why the following function isnt' working.
I am a bit new to more than basic async with javascript, so I don't think this has anything to do with anything other than bad js.
This works fine but having a wrapper is pretty pointless:
// wrapper
function asyncLoad(className, id, callback) {
redisClient.hget(className, id, callback);
}
// execution
asyncLoad('Person',1234,function(err,res) {
if (err) {
console.log(err);
} else {
var obj = JSON.parse(res);
console.log(obj);
}
});
I thought it would be useful for debugging and repetition if I could do this, but I'm definitely doing something wrong...
// wrapper
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res,callback) {
console.log(callback);
if (err) {
console.log(err);
} else {
var obj = JSON.parse(res);
callback(obj);
}
});
}
// execution
asyncLoad2('Person',1234,function(obj) {
//simpler way to get back a parsed object with error handling already done
}
Thanks in advance!
PS - I'm aware that this is really lame error handling; I'm not expecting to use it all the time, just for select things and especially during debugging.
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res,callback) {
Here you expect the redisClient to pass you the callback - but it doesn't, it just will pass the two err and res arguments. The callback parameter shadows the callback variable from the asyncLoad2 function, you will not be able to access it. Remove the parameter:
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res) {
// now refer to the actual `callback` that was passed into `asyncLoad2`
For reference, here's the final function; error logging is automatic and you can do something else with the errors if you want, and you always get back a parsed hash, which is nice DRY:
// wrapper
function asyncLoad(className, id, callback) {
redisClient.hget(className, id, function(e,r) {
if (e || !r) {
console.log('Error retrieving from database: ');
console.log(e);
callback(e,r);
} else {
var parsed = JSON.parse(r);
callback(e,parsed);
}
});
}
// use
asyncLoad('Person',1234, function(e,r) {
if (e) {
// do something besides just log
} else {
// the rest of your stuff here
}
});
And I even figured I could metaprogram reconstruction of the full object (since jsonified strings lack prototypes or functions), although this technique relies on the way I've written (and thoroughly tested!) my constructors and should be used extremely carefully:
...
var parsed = JSON.parse(r);
var obj = reconstructObj(className, parsed);
callback(e,obj);
...
function reconstructObj(className,hash) {
//instantiate a new object of the correct class
var obj = eval('new ' + className + '()');
//overwrite the properties from the hash values
for (prop in hash) {
obj[prop] = hash[prop];
}
return obj;
}
I looked at this:
Calling a JavaScript function named in a variable
But it doesn't answer my question.
This normally works:
window['class']['sub_class']['function_name'](data);
But now I'm trying to make a general function that can handle any depth:
function callbackFunction(callback, data){
//callback = a.b.c, or a.b, or a
callback = explode(callback);
//I need to be able to call callbackFunction and somehow callback and form their proper form below
window[callback.a](data);
//or
window[callback.a][callback.b](data);
//or
window[callback.a][callback.b][callback.c](data);
}
I believe the duplicate suggested by Bergi will only solve half of your problem. Since your final value will be a function, and since that function is a member of an object, you'll end up executing it in the wrong context (i.e., with the wrong this value).
I suggest you use something like this:
function getCallback(path) {
var arr = path.split('.');
var k;
var fn = window;
while(k = arr.shift()) {
if(typeof fn[k] === "function") {
fn = fn[k].bind(fn);
} else {
fn = fn[k];
}
}
if(typeof fn === "function") return fn;
return function(){};
}
http://jsfiddle.net/7CEd5/
Compare the value of this in the callback with what you get by using the answers to Convert string in dot notation to get the object reference.
You can chain references to objects/sub-objects/etc for however long you want. If you have a point-delimited string (e.g. "document.blah.blah2.method"), then you need to split it to individual tokens (e.g. ["document", "blah", "blah2", "method"]).
Then it's simply a matter of looping through the chain:
var c = window;
for (var i = 0; i < chain.length - 1; i++) {
c = c[chain[i]];
}
c[chain[chain.length-1]](some_arguments);
I am newbie about javascript.So I do not know what is the name of I looking for and How do I do it?
After you read question if you thing question title is wrong, you should change title.
I am using console.log for debugging but this is causing error if browser IE. I made below function for this problem.
var mylog=function(){
if (devmode && window.console){
console.log(arguments);
}
};
mylog("debugging");
Now I want to use all console functions without error and I can do that as below.
var myconsole={
log:function(){
if (devmode && window.console){
console.log(arguments);
}
}
,error:function(){
if (devmode && window.console){
console.error(arguments);
}
}
...
...
...
};
But I do not want to add all console functions to myconsole object severally.
I can do that in PHP with below code.
class MyConsole
{
function __call($func,$args)
{
if ($devmode && function_exists('Console')){
Console::$func($args); // Suppose that there is Console class.
}
}
}
MyConsole::warn("name",$name);
MyConsole::error("lastname",$lastname);
This is possible with __noSuchMethod__ method but this is specific to only firefox.
Thanks for helping.
Unfortunately, you can't do that in JavaScript, the language doesn't have support for the "no such method" concept.
Two options for you:
Option 1:
Use strings for your method name, e.g.:
function myconsole(method) {
var args;
if (devmode && window.console) {
args = Array.prototype.slice.apply(arguments, 1);
window.console[method].apply(window.console, args);
}
}
Usage:
myconsole("log", "message");
myconsole("error", "errormessage");
The meat of myconsole is here:
args = Array.prototype.slice.apply(arguments, 1);
window.console[method].apply(window.console, args);
The first line copies all of the arguments supplied to myconsole except the first one (which is the name of the method we want to use). The second line retrieves the function object for the property named by the string in method from the console object and then calls it via the JavaScript apply function, giving it those arguments.
Option 2:
A second alternative came to me which is best expressed directly in code:
var myconsole = (function() {
var methods = "log debug info warn error assert clear dir dirxml trace group groupCollapsed groupEnd time timeEnd profile profileEnd count exception table".split(' '),
index,
myconsole = {},
realconsole = window.console;
for (index = 0; index < methods.length; ++index) {
proxy(methods[index]);
}
function proxy(method) {
if (!devmode || !realconsole || typeof realconsole[method] !== 'function') {
myconsole[method] = noop;
}
else {
myconsole[method] = function() {
return realconsole[method].apply(realconsole, arguments);
};
}
}
function noop() {
}
return myconsole;
})();
Then you just call log, warn, etc., on myconsole as normal.
This question already has answers here:
Test for existence of nested JavaScript object key
(64 answers)
Closed 8 years ago.
I have to check deeply-nested object property such as YAHOO.Foo.Bar.xyz.
The code I'm currently using is
if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
}
This works, but looks clumsy.
Is there any better way to check such deeply nested property?
If you expect YAHOO.Foo.Bar to be a valid object, but want to make your code bulletproof just in case it isn't, then it can be cleanest to just put a try catch around it and let one error handler catch any missing segment. Then, you can just use one if condition instead of four that will detect if the terminal property exists and a catch handler to catch things if the intermediate objects don't exist:
try {
if (YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// handle error here
}
or, depending upon how your code works, it might even just be this:
try {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}
I particularly use these when dealing with foreign input that is supposed to be of a particular format, but invalid input is a possibility that I want to catch and handle myself rather than just letting an exception propagate upwards.
In general, some javascript developers under-use try/catch. I find that I can sometimes replace 5-10 if statements checking input with a single try/catch around a larger function block and make the code a lot simpler and more readable at the same time. Obviously, when this is appropriate depends upon the particular code, but it's definitely worth considering.
FYI, if the usual operation is to not throw an exception with the try/catch, it can be a lot faster than a bunch of if statements too.
If you don't want to use the exception handler, you can create a function to test any arbitrary path for you:
function checkPath(base, path) {
var current = base;
var components = path.split(".");
for (var i = 0; i < components.length; i++) {
if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
return false;
}
current = current[components[i]];
}
return true;
}
Example usage:
var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
// a.b.c.d exists and can be safely accessed
}
var _ = {};
var x = ((YAHOO.Foo || _).Bar || _).xyz;
Consider this utility function:
function defined(ref, strNames) {
var name;
var arrNames = strNames.split('.');
while (name = arrNames.shift()) {
if (!ref.hasOwnProperty(name)) return false;
ref = ref[name];
}
return true;
}
Usage:
if (defined(YAHOO, 'Foo.Bar.xyz')) {
// operate on YAHOO.Foo.Bar.xyz
}
Live demo: http://jsfiddle.net/DWefK/5/
If you need to check the correctness of the path, rather than the existance of the "xyz" member on the "YAHOO.Foo.Bar" object, it will probably be easiest to wrap the call in a try catch:
var xyz;
try {
xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
// fail;
};
Alternately, you can do some string-kong-fu-magicTM:
function checkExists (key, obj) {
obj = obj || window;
key = key.split(".");
if (typeof obj !== "object") {
return false;
}
while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ;
return (!key.length && typeof obj !== "undefined");
}
The use as follows:
if (checkExists("YAHOO.Foo.Bar.xyz")) {
// Woo!
};
This problem is solved quite beautifully by coffeescript (which compiles down to javascript):
if YAHOO.Foo?.Bar?.xyz
// operate on YAHOO.Foo.Bar.xyz
use a try catch.
a={
b:{}
};
//a.b.c.d?true:false; Errors and stops the program.
try{
a.b.c.d;
}
catch(e){
console.log(e);//Log the error
console.log(a.b);//This will run
}
I actually voted to close the question as duplicate of javascript convert dotnotation string into objects.
However, I guess it's a different topic, but the answer there might still be helpful if you don't want to try-catch all the time.