<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