Reading a Javascript Object - javascript

How do I read a Javascript Object when I don't know what's in it?
I've been working on node.js and have a variable for which I really don't know what's in it. When I try sys.puts:
sys.puts(headers) // returns [object Object]
If there was something like a print_r in javascript, that would have been fine.

You can loop over its properties with
for (var item in headers)
{
// item is the name of the property
// headers[item] is the value
}
example at http://www.jsfiddle.net/gaby/CVJry/3/ (requires console)
If you want to limit the results to direct properties (not inherited through the prototype chain) then use as well the hasOwnProperty method.
example at http://www.jsfiddle.net/gaby/CVJry/2/

Most web browsers can use the JSON-object to print the contents of an object,
writeln(JSON.stringify(your_object));
If that fails, you can create your own stringifier;
var stringify = function(current) {
if (typeof current != 'object')
return current;
var contents = '{';
for (property in current) {
contents += property + ": " + stringify(current[property]) + ", ";
}
return contents.substring(0, contents.length - 2) + "}";
}
var my_object = {my_string: 'One', another_object: {extra: 'Two'}};
writeln(stringify(my_object));

You can loop through your object to know its properties & their values
Suppose your object is
var emp = {
name:'abc',
age:12,
designation:'A'
}
Now you can read its details in JS
for(property in emp ){
alert(emp[property] + " " +property);
}
If you have firebug in added in your Firefox browser, open it & write either in JS or JS window in Firebug console.
console.log(a);

If you need it just to check what's in an object (ie, it's relevant to you for some reason, but you don't need that functionality in your script), you can just use Firebug to get the object and check exactly what's in it.

Related

Make object Object as index of array (Javascript)

I've been using a crossword app from this repo: https://github.com/jweisbeck/Crossword . The problem is that the program uses jquery version 1.6.2 and my whole project uses jquery-3.1.1 version. Particularly, the error arises here:
buildEntries: function() {
var puzzCells = $('#puzzle td'),
light,
$groupedLights,
hasOffset = false,
positionOffset = entryCount - puzz.data[puzz.data.length-1].position; // diff. between total ENTRIES and highest POSITIONS
for (var x=1, p = entryCount; x <= p; ++x) {
var letters = puzz.data[x-1].answer.split('');
for (var i=0; i < entries[x-1].length; ++i) {
light = $(puzzCells +'[data-coords="' + entries[x-1][i] + '"]');
if($(light).empty()){
console.log($(light));
$(light)
.addClass('entry-' + (x-1) + ' position-' + (x-1) )
.append('<input maxlength="1" val="" type="text" tabindex="-1" />');
}
}
}
// Put entry number in first 'light' of each entry, skipping it if already present
console.log(entries);
console.log(puzz.data);
for (var i = 0; i < entryCount; i++) {
$groupedLights = $('.entry-' + i); 
if(!$('.entry-' + i +':eq(0) span').length){
$groupedLights.eq(0)
.append('<span>' + puzz.data[i].position + '</span>');
}
}
util.highlightEntry();
util.highlightClue();
$('.active').eq(0).focus();
$('.active').eq(0).select();
}
The error arises at line with
light = $(puzzCells +'[data-coords="' + entries[x-1][i] + '"]');
The browser shows this error:
Error: Syntax error, unrecognized expression [object Object][data-coords="1,6"]
I believe this is related to the jQuery version. Or maybe the program uses [object Object] as index. Not sure as I am new in jQuery. I tried to use jQuery Migrate, but it didn't help. Also, I tried to use that jQuery 1.6.2, but a web browser could not find jQuery at all as I am using Typescript and had to install jQuery through .d.ts file. Any tips or advises? Thanks in advance
As the title says:
Make object Object as index of array
That is not possible with standard Objects/Arrays, but you can use a Map for that:
let map = new Map(),
key = {id: '##'};
map.set(key, [1,2,3,4,5]);
console.log(map.get(key)); //[1,2,3,4,5]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
The [object Object] in the string shown in the error is because a jQuery object is being appended to a string to create a selector, which is invalid.
In your code, it's this line causing the problem:
var puzzCells = $('#puzzle td') // holds jQuery object
// later on...
light = $(puzzCells + '[data-coords="' + entries[x-1][i] + '"]');
This is nothing to do with the version of jQuery being used as it's a syntax issue.
To fix this you should use filter() on the puzzCells object, instead of appending it to a selector. Try this:
light = puzzCells.filter('[data-coords="' + entries[x-1][i] + '"]');
You are concatenating an object (puzzCells) and a string. When JavaScript detects an string concatenation tries to convert all the variables to strings before concatenating them. In plain JavaScript, if you do WHATEVEROBJECT.toString() you will receive [object Object], that's why you see an error containing that message.
This is not jQuery version problem, as this happens at the very low level (JavaScript).
puzzCells is a jQuery object, where you can call jQuery methods. In this case you need the filter method, like this:
light = puzzCells.filter('[data-coords="' + entries[x-1][i] + '"]');
Check out more info right here: http://api.jquery.com/filter/

Can I access a variable's name as a string after passing it as an argument to another function?

Perhaps a slightly dim question but I'm trying to design something where I'm using javascript / jquery to change the layout of a website and I'd like to see the values of both a variable name and it's current value in another div.
I was just doing $test.append('example string' + exampleVar) a lot so I thought I would make a function called test().
So far I have:
function test (test) {
$test = $('.test');
$test.append(test+"<br>");
}
and then would pass it a variable name as an argument but I can't find any way of making it display the name as a string. I know about making it as an object to access the key and value but that doesn't really seem to work here?
Bit of a long-winded way to do it, but here's an example using an object:
function tester(options) {
var keys = Object.keys(options);
console.log(keys[0] + ': ' + options[keys[0]]); // test: My value
}
tester({ test: 'My value' });
DEMO
You could use a feature of javascript where obj["prop"] is the same as obj.prop
So instead of passing the variable as a variable and hoping to get its name, you use the name as a string to get the variable's value.
If you aren't using namespaces/variables and want to a global/root variable, pass window, eg:
function test(obj, val) {
console.log(val + ": " + obj[val]);
}
var val1 = 1;
var val2 = 2;
test(window, "val1");
test(window, "val2");
(obviously you don't get the name of 'obj' - but maybe it's a start)
if you only have root/global variables (as in the example provided in the question) then you could remove obj:
function test(val) {
console.log(val + ": " + window[val]);
}
var val1 = 1;
var val2 = 2;
test("val1");
test("val2");
It seems what you want to do something like this:
var argumentName = /([^\s,]+)/g;
// fu is a function
// fu.toString look like: function myFunction (param[, param]*) { code }
function getParamNames(fu) {
var f = fu.toString();
return f.slice(f.indexOf('(')+1,f.indexOf(')')).match(argumentName);
}
Then you might want to create an helper which will take every functions:
// I choosed the console as an output, but you can set anything
function displayParameters(fu) {
var _params = getParamNames(fu);
if(_params!==null) {
for(var i=0;i<_params.length; i++) {
console.log(_params[i]);
}
} else { console.log('no parameters'); }
}
And, you will need to call: displayParameters(test);
In a function you will be using a parameter. So in that case the "variable name" will always be the name of the parameter. In this case getting the string value will always be test. I would assume this is not what you want. You were correct that the best way to do this is to use an object and iterate over the key, values. You would do this like:
var test = {
"test" : "value"
};
function test (test) {
var k, $test = $('.test');
for(k in test){
$test.append(k + "<br>");
}
}
Also, I do not think there is a way to get the variable string name. So the above would be the way to get the name of a variable.

how do javascript objects constructed with both dot and literal notation behave when called?

While running the code below, without any function calls, I would immediately get this output
["1122","3rd St","Seattle","WA","92838"]
The closest thread that addressed this code was Need Explanation: Organization with Objects in a Contact List (Javascript, Codecademy) but it didn't quite address my concern.
I'm sure that the way I had added key,value pairs to the objects is somehow yielding this output, but I can't seem to explain why, especially when running the code, there is no function call included.
When actually trying to call search (e.g. search("steve")), it would fail but it would work on search("bill"). I thought it might be related to the javascript console but I checked using Chrome's console with the same results. Any help would be much appreciated.
var friends={};
friends.bill = {};
friends.steve={};
friends.bill["firstName"]="Bill";
friends.bill["lastName"]="Gates";
friends.bill.number="333.222.3937";
friends.steve["firstName"]="Steve";
friends.steve.lastName="Ballmer";
friends.steve["number"]="829.383.3939";
friends.bill["number"]="232.8392.2382"
friends.bill.address=['5353','Cook Ave','Bellevue','CA','94838']
friends.steve.address=['1122','3rd St','Seattle','WA','92838']
var search=function(name)
{
for(var i in friends){
if (name==i["firstName"])
{
console.log(friends[i])
return friends[i]
}
else{
return "no match"
}
}
}
try changing:
for(var i in friends){
if (name==i["firstName"])
...
to
for(var i in friends){
if (name == friends[i]["firstName"])
...
You meant something like:
for(var i in friends){
if( name == i ) { //i would be either "bill" or "steve" and check against name variable
console.log("Data for:" + i + " firstname is:" + friends[i]["firstName"]);
}
}
You are seeing this output:
["1122","3rd St","Seattle","WA","92838"]
Because it is what is currently stored in $_ (Most browser based JS interpreters will spit out what is in $_ on the prompt).
$_ is the value of the last evaluated expression, which in your case is:
friends.steve.address=['1122','3rd St','Seattle','WA','92838']
The "var search ..." is actually a declaration and will therefore not be stored in $_.
Also, your search function should probably look like this:
var search = function(name) {
for(var i in friends) {
if (name.toLowerCase() == friends[i]["firstName"].toLowerCase()) {
console.log(friends[i])
return friends[i]
}
}
return "no match";
};
#cherniv might have beat me to the punch on moving the return out.

Is there a way to prevent undefined javascript variables from displaying 'undefined' when inserted into html?

I am appending text which is stored in a javascript variable into a div element. The issue is that the depending on the situation there may or may not be text stored in that variable. If there is not I end up with the text 'undefined' where the valid text would have been in the div.
so as an example:
htmlelement.innerhtml = '<h2>'+array.object.title+
'</h2><p>'+array.object.textField1+
'</p><p>'+array.object.textField2+
'</p><p>'+array.object.textfield3+'</p>';
This shows up in a function which will run for each object in the array. Not all of the objects have content in all 3 text fields.
So is there an easy way to prevent 'undefined from being printed?
Right now I have this before the previous line:
if (!array.object.textfield1) {
array.object.textfield1 = ' ';
}
if (!array.object.textfield2) {
array.object.textfield2 = ' ';
}
if (!array.object.textfield3) {
array.object.textfield3 = ' ';
}
But this is not a practical solution if there are a lot of variables that need to be checked.
Can you use the logical operator || ?
array.object.textField1||''
Note: Please do take care of values like 0 or any other falsy values .
Use "The New Idiot" answer this is here just fro an extra method.
The other answer is better because it molds the check into the logic ( a good thing!) and is better for performance.
with that said REGEX!!
htmlelement.innerText = htmlelement.innerText.replace('undefined', '');
check each array item to see if its undefined with the **typeof** operator.
for each array item if the **typeof** is **undefined** you can do eather 2 things:
1. set to default
2. remove with splice()
example:
function cleanArray(theArray){
for(i=0;i < theArray.length;i++){
if(typeof theArray[i] == "undefined"){
theArray[i]="";//OR SPLICE IT OU WITH splice()
}
}
}
//NOW CALL THIS FUNCTION EVERYTIME PASSING IT THE ARRAY
cleanArray(arrayOfItems);
no simple way around this, you need to plan your design accordingly
"The New Idiot" answer is pretty good if you only have a few. If you have a more complicated object that you want to sort out, one option would be to iterate over the properties and set them to an empty string if they are undefined. e.g.
var o = {
t1: undefined,
t2: "hey"
};
for (prop in o) {
if (o.hasOwnProperty(prop) && typeof o[prop] === "undefined") {
o[prop] = "";
}
}
jsFiddle: http://jsfiddle.net/Ca6xn/

It this javascript function possible?

When debugging I often write something like console.log("foo:"+foo+", bar:"+bar) is it possible to write a function logValues(foo,bar) which would give the same output? Essentially I'm asking if there is a way to go from a variable to that variable's name. Do I have to setting for looping for an arguments array just using the index yielding [0]: 'value of foo, [1]: 'value of bar'
Thanks for reading
Try this code:
var logValues = function(){
var args = arguments;
for(var i in args)
window.console.log(args[i] + ": " + eval(args[i]));
}
logValues("foo","bar");
(none of these options directly answer the question; but should give better alternatives for what you're trying to do)
WebKit's inspector (and I assume Firebug) allow you to log complex types, no need to write helpers at all!
Just console.log(foo, bar) and you're set. Or console.log({foo: foo, bar: bar}) if you want the variable names in the output.
Alternative Answer:
You might consider a helper that just takes an object and spits it out - it doesn't save much, if any, typing; but results in more readable code that pretty closely matches the logged output.
window.logValues = function(values) {
var k, v;
var pairs = [];
for (k in values) {
v = values[k];
pairs.push("" + k + ": " + v);
}
console.log(pairs.join(", "));
};
You then call it like:
logValues({foo: 1, bar: "asdf"})
To which you see:
foo: 1, bar: asdf
Option #3:
Or a more terse example that may strip out a little more type information than you like:
window.logValues = function(values) {
console.log(JSON.stringify(values));
}
function logValue(foo)
{
console.log(foo + ": " + eval(foo));
}
var foo = "something";
logValue("foo");
This will work, but you have to make sure that your foo variable is available inside the logValue function.
I use two arrays to store all data in:
data=[];
names=[];
foo=1;
data[1]="foovalue";
names[1]="foo";
bar=2;
data[bar]=28;
names[bar]="bar";
etcetera, all global values that I use in a project
Next you can write code like
data[foo]=data[foo] + data[bar];
data[bar]=data[bar]+22;
function log(a,b){
//something like
var=text;
text=names[a] + " = " + data[a];
text=text + linebreak + names[b] + " = " + data[b];
}
you can also use it to write to html;
function writedataval(arrnumber){
document.getElementById(names[arrnumber] ).innerHTML = data[arrnumber] ;
}
writedataval(foo);
There has to be a tag with id="foo" before you can run this code succesfully
I think this approach very beneficial in many ways as you can also use the array indexes to acces data and name .

Categories

Resources