<form> <label>Name:</label> <input type="text" name="name" /> <label>Address:</label> <input type="text" name="address" /> <input type="button" value="register" /> </form> <div data-element="output"></div>
var Module = { collectData: function(cb) { var name = $('[name="name"]').val(); var address = $('[name="address"]').val(); if(name != '' && address != '') { cb(null, { name: name, address: address }); } else { cb({msg: 'Missing data'}); } }, error: function(err) { $('[data-element="output"]').html(err.msg); }, success: function(data) { $('[data-element="output"]').html('Hello ' + data.name + '!'); } }
collectData
function collects values from fields and checks if the user has entered anything. If not, a callback occurs with the transmitted object containing a short error message. If everything is OK, the function responds with null in the first argument and an object containing the data as the second parameter. The developer using the module must check if the object of the error is transmitted. If the error is not passed, then the second argument passed can be used. For example: $('[value="register"]').on('click', function() { Module.collectData(function(err, data) { if(typeof err === 'object') { Module.error(err); } else { Module.success(data); } }); });
err
parameter is an object, and if so, we display an error message. If you look at the code, you can find the problem, but for now let's see how everything works:Uncaught TypeError: Cannot read property 'msg' of nullLet's track down and correct this error.
error
method from our module gets something that is null
. And of course, null
does not have the msg
property. This is why the browser throws an error. The error
function is called only in one place. Let's set a breakpoint and see what happens:data
and error
is null
, and this is the right behavior. Thus, the problem must be somewhere in the if
clause. Add console.log
and see if we are moving in the right direction: Module.collectData(function(err, data) { console.log(typeof err); if(typeof err === 'object') { Module.error(err); } else { Module.success(data); } });
typeof err
returns an object
. That is why we always show an error.if
construct to if (err)
and our little experiment will work as expected.if
construct. Wouldn't it be better if we had a tool available directly from our code? A library that provides the same information as the debugger, but is inside the console? So, Deb.js is the answer to this question..deb()
after the function definition. Note that the type err
placed inside the function. Thus, we do not need to look for it. Returns are also grouped and colored. Each function we are debugging will be printed in a separate color. Let's fix our mistake and put another deb()
to see what it looks like.console.log
instructions, we will see them inside the function, at the place where they occur. There is even an opportunity to leave the description of functions, for the best their recognition.debc
, not deb
. This is the same function, only with minimized output. If you start using Deb.js , you will very quickly notice that you do not always need to see all the details.console.log
calls. He suggested creating a new error and getting a trace from there: ['log', 'warn'].forEach(function(method) { var old = console[method]; console[method] = function() { var stack = (new Error()).stack.split(/\n/); // Chrome includes a single "Error" line, FF doesn't. if (stack[0].indexOf('Error') === 0) { stack = stack.slice(1); } var args = [].slice.apply(arguments).concat([stack[1].trim()]); return old.apply(console, args); }; })
Function.prototype
. For example: Function.prototype.awesome = function() { var original = this; return function() { console.log('before'); var args = Array.prototype.slice.call(arguments, 0); var res = original.apply(this, args); console.log('after'); return res; } } var doSomething = function(value) { return value * 2; }.awesome(); console.log(doSomething(42));
this
in our method points to the base class of the function. We can call the method to which we connect, later when we need it, this is exactly what we need, since we can track the time before and after execution. At the same time, we are returning our own function, which now works as a proxy. We used .apply(this, args)
to save context and passed arguments. And thanks to Remy’s hint, we can also get a stack trace.console.group
and console.groupEnd
, which greatly improve visual display during logging. Chrome even allows us to color the displayed information in different colors.Source: https://habr.com/ru/post/228819/
All Articles