How can I find the value of this variable in firefox debugger? - javascript

I am new to debugging JavaScript and AngularJS. I have breakpoints in virtually every line of the following code segment, but I am not able to find the response variable or data or content in the Firefox debugger. There is a very dense nested structure of variables in the debugger. Where do I look in the Firefox debugger variables structure to find the values for response or data or content in the code below?
The alert says that the confirmStatus variable's value has not changed from its default and thus was not populated by the call to the backend service, even though the backend service call produced console logs indicating that it was fired. I want to find out what is coming back and in what form so that I can alter the client side code below.
Here is the segment of Javascript code that I am running through the debugger:
$scope.$on('$viewContentLoaded', function() {
var str1 = "/confirm-email?d=";
var str2 = $routeParams.d;
var res = str1.concat(str2);
$http.post(res).then(function(response) {
$scope.confirmStatus = response.data.content;
});
var str3 = "confirmStatus is: ";
alert(str3.concat($scope.confirmStatus))
alert("viewContentLoaded!")
});

I would suggest using the debugger first. This means:
open the debugger with the developer tools menu or keyboard shortcut: https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Open_the_debugger
Pick the file you want to debug, key shortcut is on mac, then type in part of your .js file to have it open in the debugger.
You should see the source code for your .js file now, and you can click in the left-nav to the line you want to stop on, e.g. the $scope.confirmStatus = ....
There is also a good trick with angular where you can access the scope from the console. To do this
Again open the developer tools this time to the console not debugger
Right-click on the page near some html owned by angular, and pick "Inspect element"
In the console: angular.element($0).scope(), and you will have access to the controller scope for that element.
That said, you might want to try and capture the error handler for the http.post. e.g.
$http.post(res).then(function(response) {},
function(err) {});

Keep in mind that this function will run in parallel to current one, at a later stage when response will come from server:
function(response) {
$scope.confirmStatus = response.data.content;
}
You should put a debugger break point into this $http callback function -- response variable will be destroyed as soon as callback function execution will end.
Your alert will always display unmodified confirmStatus, because confirmStatus is changed in callback function which will be executed later when response will come from server.

Related

Set a test collection variable accessible for each request test in Postman

In Postman, after each request I execute this sequence of code almost every time in the test:
var jsonData = pm.response.json();
// Do something useful with jsonData variable
Is it possible to put this declaration inside the collection test so that I can use it in each of my request test without having to rewrite it every time ?
Currently, if I set it inside my collection test and then try to use the variable jsonData in my request test, the variable doesn't exist.
I could set it in a global variable or environment variable I guess, but this seems not to be the right way.
According to Postman data variables as JSON should be used as global/environment variables:
The Collection Runner lets you import a CSV or a JSON file, and then use the values from the data file inside HTTP requests and scripts. We call these ’data variables’.
To use them inside Postman, follow the same syntax as environment or global variables.
So use pm.environment.set() or pm.globals.set() for your jsonData
Is it possible to put this declaration inside the collection test so
that I can use it in each of my request test without having to
rewrite it every time ?
No, that's not possible.
Read on if you want to know how I came to this conclusion.
I made a simple little experiment. You can replicate it as below.
I have created a Postman collection by the name TestCollection.
It can be downloaded and saved to your local drive from:
https://user.it.uu.se/%7Ehesc0353/postman/TestCollection.pm_coll.json.
Then - from the Postman desktop app (not the chrome extension) - the
TestCollection can be imported as shown in the figure below.
(Collections > Import > File > Upload Files)
To open the collection window, click on the three mini circles (•••)
next to the collection name.
Then click Edit as in the figure below.
As shown below, click the Tests tab.
The JavaScript snippet for the test of the collection is:
pm.test('Collection Test', function () {
pm.response.to.have.status(200);
});
console.log('Hello from Collection Test!');
const jsonData = pm.response.json();
console.log('Collection Test says URL = ' + jsonData.url);
The // Do something useful with jsonData variable in the question is
in this case to print the URL of the request in the console.
Next click on the TestCollection-Request ...
... and then on its Tests tab.
(The GET request is https://postman-echo.com/get
– Click the image to make it larger.)
The JavaScript snippet for the test of the request is:
pm.test('Request Test', function () {
pm.response.to.have.status(200);
});
console.log('Hi from Request Test.');
const jsonData = pm.response.json();
console.log('Request Test says user-agent = ' +
jsonData.headers['user-agent']);
This time, the // Do something useful with jsonData variable in the
question is to print the user-agent of the request in the console.
Click the blue Send button ...
... and then open the Console in the bottom left corner.
The output in the console shows that the collection test runs before
the request test.
To answer the question asked, in the second JavaScript code snippet
(belonging to the request) we should comment out the declaration
(and initialization) of the jsonData variable, and then see what
happens when the request is sent again.
The result of doing this is shown the figure below.
As the figure shows, this results in a
ReferenceError: jsonData is not defined.
I think it is rather obvious what is going on here. Once the scope of
the second JavaScript code snippet becomes alive, the scope of
the first JavaScript code snippet (belonging to the collection)
is already dead.
This means that - in the second code snippet - the jsonData
variable is not available.
To confirm this result, consider what will happen if - in the second
code snippet only - we (uncomment line 5 and) rename the jsonData
variable to say otherJson.
See the result in the figure below.
Confirmed! - Even though jsonData of the collection snippet and
otherJson of the request snippet contain the exact same data,
they are still two completely different and unrelated JavaScript
variables belonging to two completely different and unrelated scopes.
Think of the two code snippets being in two different files, if that
helps.
References
Postman: The Easy Way to Work with APIs
Types of Scope

How to set a breakpoint in standard/native JavaScript functions?

Can I set a breakpoint on a standard JavaScript function? For example, can I pause the debugger every time context.beginPath() is called? Or every time that String.replace() is called?
UPDATE: What I meant by standard JavaScript function is functions built-in into the JavaScript engines.
Yes you can do this by overriding the original functionality by performing the following two steps:
Make a copy(reference really) of the original function:
mylog = console.log;
Override the original with your copy inserting the debugger statement:
console.log = function(){
debugger;
mylog.apply(this, arguments);
}
Now when called console.log will perform a breakpoint. (Note you'll have to handle different function arguments differently depending on the function be overriden)
Here is another example using an instance methods, for example String.prototype.replace:
let originalFunction = String.prototype.replace;
String.prototype.replace = function(...args) {
debugger;
return originalFunction.call(this, ...args);
}
console.log('foo bar baz'.replace('bar', 'BAR'));
Are you looking for the debugger statement?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
There are 3 ways to set up a breakpoint and debug the code.
1. Chrome dev-tools / Firebug:
Using Chrome developer tools or firebug to locate the line of
JavaScript, then set the breakpoint with the mouse. In chrome, you
should first open(ctrl+shirt+I) to open developer tools.
Select the script tab or click on (ctrl+P) to open then desired file.
Search the line on which you wanted to set a breakpoint and set a
breakpoint.
Whenever you execute your code next time in a browser, the breakpoint
is fired. In watch section, you may see every expression, all
variables in scope, and the call stack too.
2. Debugger
Using debugger statement, it fires every time and it helps when it
hard to find the execution of code.
debugger;
3. Webstorm IDE / Visual Studio Code
Webstorm IDE/Visual Studio Code have the facility to debug a code from
IDE.
Javascript is a really flexible language and probably following the way to override existing javascript and debug method then please use following a way of debugging.
var fnSetAttribute = Element.prototype.setAttribute;
Element.prototype.setAttribute = function(name, value) {
if (name == 'clone') {
debugger; /* break if script sets the 'clone' attribute */
}
fnSetAttribute.call(this,name,value); /* call original function to
ensure those other attributes are set correctly */
};
For more reference please review https://alistapart.com/article/advanced-debugging-with-javascript
Works in Google Chrome Console:
debug(console.log) // sets a breakpoint on "console.log" builtin
console.log("Hello")
It shows the Sources pane and says
🛈 Paused on debugged function

Setting window.location in JavaScript hangs

I have an ASP.NET MVC app. My app uses jQuery on the client side. The user can enter values into several fields and click "Refresh". The Refresh is behaving oddly.
When Refresh is clicked, I execute the following JavaScript:
function refresh() {
var chosen = "(someField eq 'value')";
try {
if (chosen) {
var url = 'http://localhost:8089/item&c=' + chosen;
alert(url);
window.location = url;
} else {
window.location = 'http://localhost:8089/item';
}
return false;
} catch (ex1) {
alert(ex1);
}
}
The value for chosen is actually generated via a function. I've noticed when I use a certain type of control, the page hangs. Here is what is odd, I can see the request made in Fiddler. Yet, my breakpoint in my controller action is never hit. If I copy and paste the url from the alert call into the address bar, my breakpoint gets successfully hit. So, I'm totally confused.
Due to the fact this involves a specific control, I at first assumed this was a JavaScript error. However, I do not see any JavaScript error in the console. I also checked to see if any exceptions were being swallowed and I did not see any.
The fact I see the request in Fiddler, would imply that I'm getting to the web server. Yet, if I have a breakpoint on the very first line of the controller action, I would expected that to trip. It does not trip in the scenario where I use the control. It does trip if I do NOT use the control. The result in Fiddler sits at '-'. It never returns. Plus, I do not get an exception thrown in my ASP.NET view.
I'm totally stuck on this and looking for ideas of potential causes. Thank you.
This behavior is usually the result of a problem during model binding for the controller.
A quick step to try is making sure the query string values you are sending are properly encoded.
var chosen = "(someField eq 'value')";
chosen = encodeURIComponent(chosen);
Would eliminate any bad character problems that the model binder might be having.

Where are the Web Console objects in Firefox Devtools?

I found a way to inject information into the Firefox Web Console, catching and modifying the return value of createMessageNode, modifying the web-console output:
Oddly enough, the elements returned don't seem to have any possible way to link them back to the object they represent - yet when you click [object Array], it always pops up to the right. How is this connected?
As a side note, when I click upward on the breadcrumbs to see where it came from on the stack trace, some items aren't shown in the debugger. Is this a bug, or are some JS modules compiled so as to never show their contents here? Is this the correct place to add in an array to the console line instead of always saying [object Array] etc.?
Update You can see and run this code above in this branch: https://github.com/programmin1/DevTools-Tweaks/tree/webconsoleOutputBetter
by inject info do you mean Services.console.logStringMessage and stuff?
https://developer.mozilla.org/en-US/docs/Console_service
If you want to access the chrome of the web console do this:
var devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
var HUDService = devtools.require("devtools/webconsole/hudservice");
var hud = HUDService.getBrowserConsole();
var btnClear = hud.chromeWindow.document.querySelector('.webconsole-clear-console-button');
btnClear.addEventListener('mouseover', function() {
hud.jsterm.clearOutput(true);
}, false);
var fieldFilter = hud.chromeWindow.document.querySelector('.hud-filter-box');
fieldFilter.value = 'rawr'
this code access the crhome window, you can access all the text dumped there. this example above modies the filter value, and also makes the clear button clear the web console on mouseoever, just an example of how to access web console if thats what you're doing

ZKOSS Failed to process setAttr Cannot call method 'set' of null (TypeError)

I am pulling my hairs.
I have ZK grid then within the grid there's another grid.
Both are bound to separate view models.
Think about it as a social network wall.
Outer Grid is a ViewModel that render posts.
Then for each post an inner grid is used which is bound to another ViewModel to render comments.
Okay, the issue is "Failed to process setAttr Cannot call method 'set' of null (TypeError)"
HOW TO DEBUG THIS ERROR. No server side error at all. By the way code works fine but every now and then I start get this error.
I am using ZK 6.5.1.1 the latest version.
Note: I know without code it would harder to analyse the problem. But it's not too simple for me to post a portion of working or useful code snippet. So I would appreciate if someone knows how to debug this dreaded message. Also I see other type of similar messages: Failed to mount: cannot call replaceWidget of null etc etc.
Thanks
Regarding to debug this kind of issue, you can try something like below:
.1. Open the debug mode (see ref)
zk.xml
<zk>
<client-config>
<debug-js>true</debug-js>
</client-config>
<library-property>
<name>org.zkoss.web.classWebResource.cache</name>
<value>false</value>
</library-property>
</zk>
.2. Try reproduce this issue, here I create a sample to reproduce a similar issue by unbind a component manually as below (click 'test' button to see the similar error)
test.zul
<zk>
<textbox id="tbx" />
<button label="test">
<attribute name="onClick"><![CDATA[
String uuid = tbx.getUuid();
Clients.evalJavaScript("zk.Widget.$('$tbx').unbind();");
tbx.setValue("abc");
]]></attribute>
</button>
</zk>
.3. See the error message in chrome's developer tooles then click the source link:
.4. Left click on the first line under setAttr to add a breakpoint.
.5. Refersh page and click the 'test' button again, we can see the 'wgt' is null at right side, wgt usually denotes a widget (the Component at client side).
.6. Now what we know is a widget becomes null and then ZK executing setAttr command of it, to debug this, we can simply log every uuid and className while bind_ is called (bind_ is a function of widget's life cycle, basically instanciate all dom elements of a widget) by Client Side Programming, and log all widget again while button clicked.
e.g.,
test.zul (updated)
<zk>
<script><![CDATA[
var allUuids = [];
zk.afterLoad("zul", function () {
var _wgt = {};
// override zk.Widget,
// basically zk.Widget is the
// root of all widget classes
zk.override(zk.Widget.prototype, _wgt, {
bind_: function (a, b, c) {
// call original function
_wgt.bind_.apply(this, arguments);
// each widget has a uuid and className
allUuids.push({uuid: this.uuid, ele: this.className});
}
});
});
function showAllUuids () {
var info,
wgt;
for (var i = 0; i < allUuids.length; i++) {
info = allUuids[i];
// get widget by uuid
wgt = zk.Widget.$('#'+info.uuid);
// show the old className and current status
// you can also try record some more information as needed
// e.g., parent, previousSibling, sclass, etc
zk.log(info.uuid + ' was ' + info.ele + ' now ' + (wgt? wgt.className : wgt));
}
}
]]></script>
<textbox id="tbx" />
<button label="test">
<attribute name="onClick"><![CDATA[
String uuid = tbx.getUuid();
Clients.evalJavaScript("zk.Widget.$('$tbx').unbind();");
tbx.setValue("abc");
Clients.evalJavaScript("showAllUuids();");
]]></attribute>
</button>
</zk>
.7. Now we will get the log message below with the updated zul page after 'test' button clicked and let us know a textbox widget becoms null at client side, you can also check the response value in Network of chromes developer tooles.
Hope this helps
References :
ZK Client Side Programming
Open the debug mode
bind_ in zk.Widget
This particular error seems due to updating a component that is already detached/removed from ZK desktop. In other words, on server side you have a reference to a component that is cached but no longer attached to the component tree. When you try to update it ZK might try to sync its status with its corresponding Widget on client side. However since it was detached, it no longer exists in client side so calling a setAttr on a null widget gives you this error.
Although the best answer possible is already provided I wanted to add I was hitting this error and after debugging it turned out that there was a hflex="min" in a grid component. I changed this to hflex="1" and the error went away. This error started after updating zk version several versions at once so I'm not sure between which versions this change occurred but was a hard to identify. Hopefully simply searching your code base for hflex="min" might save someone some time... I would assume the same to be true for vertical flex.
It come when we are setting something to a already element which is already set previously..
like
OFCchart chart = new OFCchart;
chart.setJSONScript("somedata");
//----- Some other place setting to the same---
chart.setJSONScript("somedata");

Categories