how to access json object after loading it in d3 - javascript

I loaded a json object using d3.json and assigning the loaded json file to a global variable but when I print the global variable to the console it returns undefined, but when i type in the global variable in the chrome console it returns what I need it to. Essentially, I am just looking to load the json object be able to use it outside the d3.json function. This seems like a relatively simple task but I am a js/d3 newby so any help is greatly appreciated!
Thanks!
Code is provided below
<script type = "text/javascript" source='https://d3js.org/d3.v4.min.js'>
var gapminder;
d3.json("D3_jsondata.json", function(data){
gapminder = data;
});
//above prints in console when i type in gapminder
console.log(gapminder);//prints as 'undefined' in Chrome's console
</script>

Calling .json() gets you a promise for the body of the http response that is yet to be loaded. Try to start rendering inside the callback of the json!

For d3.json, d3.csv and d3.tsv are asynchronous request functions, so the console.log() will run before d3.json() where "gapminder" is still undefined.
After the console.log() then it's the term of d3.json() to run and you make a assignment "gapminder" with the json data, so it's not undefined anymore.

Related

Return text from URL in GTM Custom JS variable

I need to capture text from the file saved under URL (ex. https://fiddle.jshell.net/robots.txt) And return it under the function.
What is on my mind:
function(){
var url = 'https://fiddle.jshell.net/robots.txt'
var storedText;
fetch(url)
.then(function(response) {
response.text().then(function(text) {
storedText = text;
done();
});
});
function done() {
return storedText;
}
});
Unfortunately this function is not working. I received an error: Error at line 2, character 2: Parse error. primary expression expected Type: JavaScript compiler error
This should be used as a Custom JavasSript Variable in Google Tag Manager
Also this How do I return the response from an asynchronous call? is not explaining my issue and all solutions were checked by me, nothing worked due Parse error or console error.
I have to use GTM custom JavaScrip Variable, I can use anything else.
Simpler JS than better.
Function done() returns storedText value to a point of call, i. e. it works but returns nothing.
I would not recommend using an external call within a custom Custom JavasSript Variable in GTM:
You can not really control how often a Custom JavasSript Variable is executed in GTM. An it is executed a lot.
Just do the test and run a console log from a custom javascript variable.

Script not printing error in JavaScript Chrome console

I have just spent far too long trying to find a problem with the code below.
In turned out that because of the context that addRoute was called in, keys() was not returning the keys of the results object. To fix this I had to use Object.keys() despite it working without a problem in the JavaScript console (which I later realised was because of the context).
My question is, why didn't this show in my JavaScript console? It took me quite a while to realise (I have cropped the full code, the actual function is a lot bigger).
Wrong, but no error in the console:
Map.prototype.addRoute = function (results) {
var sectionsIDs = keys(results);
}
Correct
Map.prototype.addRoute = function (results) {
var sectionsIDs = Object.keys(results);
}
Your first function uses the keys console API function.
That "Command Line API Reference" page includes the warning:
Note: This API is only available from within the console itself. You cannot access the Command Line API from scripts on the page.
Thus, it is by design that the keys function only exists for code run directly on the console.
Chrome gives you a small hint about the keys function being a console-only function if you view it in the console:
> keys
function keys(object) { [Command Line API] }

Firebug's console.log: debugging asynchronous variables

I am trying to debug some javascript code. The variable I want to debug is a JS object of objects, loaded asynchronously (ajax callback). I am debugging it outside the callback.
I am pretty sure that the problem is a race-condition problem, but I want to be sure (and it is not my question).
The problem I find when debugging is that console.log gives me an information which does not make sense with what the code is doing. Therefore, either I am missing something in the code, or the result I see in the console is the not a snapshot of the state of the variable when I runned console.log.
If it turns out to be the later, how can i get a snapshot of the state of an asynchronously loaded JS object?
This is a simplified example of the code:
//This call takes a while to invoke the callback
$.get("url",function(data){
//Process data
globalVariable = data; //JSON (Object of objects)
}
//Couple lines afterwards
/* This console.log shows (in Firebug's console) "Object { }" and when I click it,
I can see the object with all its fields filled (oher objects)
*/
console.log(globalVariable);
for(var e in globalVariable){
//Does not enter here, meaning that the object is empty
}
console.log is itself asynchronous and it shows references rather than snapshots, sometimes.
If you log an object you will get a nice clickable interface where you can inspect the object. If the object changes you will see those changes reflected there.
If you want a real snapshot you're going to have to do some serialization and serializing objects is not trivial. If your objects just are data and have no functions or references you can use JSON.stringify(obj, undefined "\t").
A smarter way is to pause your asynchronous events so you can inspect the latest state of the object.
Write it like this instead. This way globalVariable will have the data before you act upon it.
$.get("url",function(data){
//Process data
globalVariable = data; //JSON (Object of objects)
for(var e in globalVariable){
//this will run
}
}

Different behavior seen accessing value in stored variable vs function call that returns the variable

Apologies for what must be a total newbie question. I'm starting to play with Backbone talking to an existing Rails app. I'm using the Console in Chrome to test out some JS functions, and I'm seeing behavior that I cannot understand.
I've defined a JS function called apiGet which just wraps a jQuery AJAX call with some custom stuff jammed into the HTTP request header.
When I call apiGet and store the result in a variable, I can then call .responseText on that variable and see the contents of that field.
However, if I just try to call .responseText on the apiGet(...) call, i.e. apiGet(...).responseText the result displayed is undefined. This makes no sense to me :-)
I'm missing something obvious -- can someone clue me in?
Here's what the console looks like:
> var url = 'http://localhost:3002/api/exercises/11';
undefined
> result = apiGet(url);
Object {readyState: 1, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
> result.responseText
"{"id":1,"number":2,"version":1,"markup":null,"html":null,"background":null}"
> apiGet(url).responseText
undefined
It looks like your function apiGet returns an xhr (request object). This will execute asynchronously, so that responseText isn't available until the response comes back from the server. When you call the property directly on the return, it happens so fast that the server hasn't responded yet, but when you use the console manually, by the time you type out result.responseText and press enter, the result is already in.
Just a guess of course, since I haven't seen the contents of getApi.

Unable to access attribute after fetch

I am testing some code in my web console (using coffescript)
#user = new Onethingaday.Models.User()
#user.url= "/users/#{current_user.get('nickname')}.json?id_type=nickname"
#user.fetch()
console.log(#user)
console.log(#user.get("facebook_id"))
The console.log(#user) line shows the following:
However, console.log(#user.get("facebook_id")) shows undefined.
I see that user has the facebook_id attribute. How do I retrieve the value of it?
This looks like a timing issue, albeit an odd one. fetch is asynchronous; you need to wait until its success callback is called before trying to access any attributes.
Try this:
#user.fetch success: =>
console.log(#user)
console.log(#user.get("facebook_id"))
It's confusing that the first console.log would show user.attributes.facebook_id existing and the second wouldn't, but console.log is itself asynchronous in Webkit's implementation, so what's going on is that the #user.get call is being resolved immediately (synchronously), whereas the object inspection in the first console.log is resolving later—after the fetch completed.
It looks like facebook_id is a property of the attributes property of the #user object. If that's the case, I'd think the following would work:
#user.attributes.facebook_id

Categories

Resources