Javascript 'undefined' when using a function variable on an array of objects - javascript

I have the following (example) array of objects:
var theArray = [
{theId:'1', num: 34},
{theId:'2', num: 23},
{theId:'5', num: 26}
];
and this function, which works fine to loop through them:
function printValues() {
var i = 0;
for(i; i<theArray.length; i++) {
var obj = theArray[i];
document.getElementById('result1').innerHTML += obj.theId + ' = ' + obj.num + '<br>';
}
}
However, if I want to abstract this function for use on similar arrays by using function variables to access objects within them, like this:
function printValuesVar(arr,elemId,arrId,arrNum) {
var i = 0;
for(i; i<arr.length; i++) {
var obj = arr[i];
document.getElementById(elemId).innerHTML += obj.arrId + ' = ' + obj.arrNum + '<br>';
}
}
'undefined' is the result when called as below (as I'd kind of expect since 'arrId' is not an object name):
printValuesVar(theArray,'result2','theId','num');
How can I use the values passed to the function's variables to access values of objects within the array by name?
rewritten following advice against antipatterns:
function printValuesVar(arr,elemId,arrId,arrNum) {
var i = 0;
var content = '';
for(i; i<arr.length; i+=1) {
var obj = arr[i];
content += obj[arrId] + ' = ' + obj[arrNum] + '<br>';
}
document.getElementById(elemId).innerHTML = content;
}

Try this:
function printValuesVar( arr, elemId, arrId, arrNum ) {
var content = '';
arr.forEach( function ( arrElem ) {
content += arrElem[ arrId ] + ' = ' + arrElem[ arrNum ] + '<br>';
});
document.getElementById( elemId ).innerHTML = content;
}
Or a bit more advanced:
function printValuesVar( arr, elemId, arrId, arrNum ) {
document.getElementById( elemId ).innerHTML = arr.map( function ( arrElem ) {
return arrElem[ arrId ] + ' = ' + arrElem[ arrNum ];
}).join( '<br>' );
}
ES5-shim for shitty browsers

Because you are loking for key "arrId", not the key stored in variable arrId
document.getElementById(elemId).innerHTML += obj[arrId] + ' = ' + obj[arrNum] + '<br>';

Related

Passing an object by it's name through HTML to javascript

It's a pretty simple question and I'm going insane over here googling this all around and getting all these insanely non related answers.
here is the code:
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
var rez += key + " = "
obj.key + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja();">klikni</button>
<div id='div1'>xd</div>
Is it possible to pass an instance of an object "zut" to this function through HTML? If yes,how,if not,how am I supposed to do it through JS?
I want div1 html to be turned into:
boja = zuta
duzina = 12
thanks for answers
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = "+ obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(zut);">klikni</button>
<div id='div1'>xd</div>
You certainly can, although why your code doesn't work is because
1) - You're re declaring the variable rezand assigning to it using += which is no valid.
2) - obj.key is not valid, because there no such property called key, To access it you need to use brackets obj[key] nowkey will be considered as a variable and it's value will be used to get the property's value.
3) - You missed a + in this line var rez += key + " = " (HERE) obj.key + "<br/>";
4) - Your call to the method in the html is missing the argument.
you can either use onclick="fja(new Banana('zuta', 12));
Or declare the object inline in the HTML, or declare it in the js and pass it name
//in the Js
var zut = new Banana("zuta", 12);
//in the HTML
onclick="fja(zut);
Example one
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = " + obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(new Banana('zuta', 12));">klikni</button>
<div id='div1'>xd</div>
Example Two
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = " + obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(zut);">klikni</button>
<div id='div1'>xd</div>

How to handle an dynamic array?

I want to show up the names of the members of an array "path" in my console.
console.log("start: ", path[0].name, "second: ", path[1].name, "third: ", path[2]name, ....)
But the problem is, that my array always changes it's size (clicking algorithm), that means sometimes it has the lenght 4 or sometimes 8 ect.
How can i adjust the console.log code to this dynamic array?
Thanks so much!
Try
path.forEach((each, i)=>{
console.log ("item" + i+ ':' + each.name );
})
Something like this:
var path = ['Prit', 'Bab', 'Nav']
var item = ["first","second", "third"];
for (i = 0; i < path.length;i++){
console.log(item[i] + ":" + path[i])
}
Try something like this for single line result set ...
var result = "";
for (var i = 0, len = path.length; i < len; i++) {
if (i !== 0) {
result += ", ";
}
result += (i + 1) + ": " + path[i].name;
}
console.log(result);
you could use a for loop here , ie,
for (var i=0;i<path.length;i++) {
console.log("item no "+ i +": " + path[i]);
}
/* Console Array */
var consoleArray = new Array;
/* Names */
var path = [
{name: 'bob'},
{name: 'jimmy'},
{name: 'chris'},
{name: 'alexander'},
{name: 'mark'}
];
/* Loop */
for(var i = 0; i < path.length; i++) {
consoleArray.push((i + 1) + ': ' + path[i].name);
}
/* Console Log */
console.log(consoleArray.join("\n"));
With ES6, you could use spread syntax ....
var path = [{ name: 'Jo'}, { name: 'John'}, { name: 'Jane'}];
console.log(...path.map((a, i) => (i ? i + 1 : 'Start') + ': ' + a.name));

recursively object to ul list and add class with index in javascript

I have a working recursive function that creates an <ul> list from an object, it works fine,
my problem is that I want to keep track of the index, and add it as class to <li> elements,
I need that the "index count system" will count in a particular way, and this is the output that I want:
class0
class0_0
class0_0_0
class0_0_1
class0_1
class0_1_0
class0_1_1
class1
class1_0
class1_0_0
class1_0_1
class1_1
class1_1_0
class1_1_1
by increasing, restarting and have maybe multiple "index count" variables in the recirsive function
This is what I'm trying, but I still can't figure out where to properly set, increase, reset the counters to achieve that result..
var i = 0;
function object2ul(data) {
var json = "<ul>";
for(var key in data) {
json = json + "<li>" +'<b>'+i+'</b>'+ key; i++;
if(typeof data[key] == 'object') {
json = json + object2ul(data[key]);
}else{ i=0;
json = json + '<ul><li>'+ data[key]+'</li></ul>';
}
json = json + "</li>";
}
return json + "</ul>";
}
document.body.innerHTML = object2ul(object);
In this example I omitted to set the classes avoiding to complicate the function
DEMO
Something like this?
var object = {
root0: {
child0: {
leaf: 'text',
leaf: 'text'
},
child1: {
leaf: 'text',
leaf: 'text'
}
},
root1: {
child0:{
leaf: 'text',
leaf: 'text'
},
child1: {
leaf: 'text',
leaf: 'text'
}
}
};
var i = 0;
function object2ul(data, prefix) {
prefix = prefix || '0'; // default
var json = "<ul>";
var childIndex = 0;
for(var key in data) {
json = json + "<li>" +'<b>'+i+'</b>'+ key; i++;
if(typeof data[key] == 'object') {
json = json + object2ul(data[key], prefix + '_' + childIndex);
}else{ i=0;
json = json + '<ul><li>'+ data[key]+'---(' + prefix + ')</li></ul>';
}
json = json + "</li>";
childIndex++;
}
return json + "</ul>";
}
document.body.innerHTML = object2ul(object);
To get the kind of indexing you want, you are going to have to use Object.keys. The following should work for an arbitrary object:
var testObj = { a: { b: '2', d: '5', e: { f: '3' } }, c: '3' };
var indexes = [];
var object2ul = function (data) {
var keys = Object.keys(data);
var json = "<ul>";
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
indexes.push(i);
json += "<li>" + "<b>" + indexes.join('_') + "</b>" + key;
if (typeof(data[key]) === 'object') {
json += object2ul(data[key]);
} else {
json += "<ul><li>" + data[key] + "</li></ul>";
}
json += "</li>";
indexes.pop();
}
return json + "</ul>";
}
document.body.innerHTML = object2ul(testObj);
Here's it in action:
JSFiddle

function writing function in JS

I have functions in JS that must be hard-coded for some reason. How do I make a function that writes this hard-coded function? Here's my example; assuming obj is a multi-array/JSON object:
function foo2(obj) {
var t = obj["key1"];
t = t["key2"];
return t;
}
function fooN(obj) {
var t = obj["key1"];
t = t["key2"];
...//more goes here
t = t["keyN"];
return t;
}
I know there're easier ways to access multi-array/object, but hard-coded functions like this is by far the fastest, since there is no variable substitution. Thank you.
I don't advocate it, but here's how you could do it:
function defineAccessor(propArray) {
var accessors = propArray.join('.');
return new Function('obj', 'return obj.' + accessors);
}
var x = { key1: { key2: 3 } };
var foo2 = defineAccessor(['key1', 'key2']);
alert(foo2(x)); // alerts 3
Seems like some strange requirements, but a possible solution is to add the functions to window using window['foo' + number].
The main tricky bit in this solution is the closure in the middle that ensures that the correct value of i is used. This is done by calling a function that takes i as an arg and returns a function.
var N = 5;
fooX = function(obj, x) {
var t = obj["key" + 1];
for (var i = 2; i <= x; i++) {
t = t["key" + i];
}
return t;
}
for (var i = 1; i <= N; i++) {
window['foo' + i] = (function(x) {
return function(obj) {
return fooX(obj, x);
}
})(i);
}
var obj = {
key1: {
key2: {
key3: {
key4: {
key5: 5
}
}
}
}
}
var message = "Results:<br>" +
"foo1(obj) = " + foo1(obj) + "<br>" +
"foo2(obj) = " + foo2(obj) + "<br>" +
"foo3(obj) = " + foo3(obj) + "<br>" +
"foo4(obj) = " + foo4(obj) + "<br>" +
"foo5(obj) = " + foo5(obj);
document.body.innerHTML = message;

Iterate all JSON objct and put into html

I need to loop all the json object and frame into html. I can iterate all the json object but I could not get only one json object(first json object).
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
obj = JSON.parse(res);
console.log('response length:' + obj.length);
for (var i = 0; i < obj.length; i++) {
var finalResult = "";
var objects = obj[i];
for (var key in objects) {
var res = "<tr><td>" + objects.ID + "</td><td>" + objects.mobile + "</td><td>" + objects.feedback + "</td><td></tr>";
console.log('res:' + res);
finalResult = res.concat(res);
console.log('finalResult:' + finalResult);
}
}
And i am unable to put everything into 'tr' element since javascript doest not have stringbuffer. I think it can be by using StringBuffer in java. How can it be done using javascript/jquery?
Pls help me.
The issue is because you're redefining the variable you're looping over, obj, within the iterating function.
As you've tagged this using jQuery, so here's a shorter alternative using $.each to build the table:
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
var phones = JSON.parse(res);
$.each(phones, function(i, obj) {
$('<tr />')
.append('<td>' + obj.ID + '</td><td>' + obj.mobile + '</td><td>' + obj.feedback + '</td><td>')
.appendTo('table');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table></table>
You don't need the inner for loop, you can access your elements directly. I made a couple of other changes as well that can be found below:
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
obj = JSON.parse(res);
var finalResult = "";
console.log('response length:' + obj.length);
for (var i = 0; i < obj.length; i++) {
var str1 = "aasd";
var tableRow = "<tr><td>" + obj[i]["ID"] + "</td><td>" + obj[i]["mobile"] + "</td><td>" + obj[i]["feedback"] + "</td><td></tr>";
finalResult += tableRow;
}
console.log('finalResult:' + finalResult);
I hope you find it helpful.
You are redefining obj in the middle of your code:
var obj = obj[i];
Use another name:
You are also resetting your finalResult inside the loop (and the inner loop is not required):
http://jsfiddle.net/7j52myca/
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
var phones = JSON.parse(res);
console.log('response length:' + phones.length);
var finalResult = "";
for (var i = 0; i < phones.length; i++) {
var str1 = "aasd";
var obj = phones[i];
var res = "<tr><td>" + obj.ID + "</td><td>" + obj.mobile + "</td><td>" + obj.feedback + "</td><td></tr>";
console.log('res:' + res);
finalResult += res;
}
console.log('finalResult:' + finalResult);
$('#result').append(finalResult);
You can do the same thing a lot shorter using pure jQuery, but #Rory McCrossan has already posted a good version like that so I will not bother adding one here.
I think you want to do this:
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
obj = JSON.parse(res);
console.log('response length:' + obj.length);
var finalResult = "";
for (var i = 0; i < obj.length; i++) {
var str1 = "aasd";
var obj1 = obj[i];
for (var key in obj1) {
var res = "<tr><td>" + obj1.ID + "</td><td>" + obj1.mobile + "</td><td>" + obj1.feedback + "</td><td></tr>";
//console.log('res:' + res);
finalResult += res;
}
}
console.log('finalResult:' + finalResult);
use jquery each method you can do it
var res = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
obj = JSON.parse(res);
var finalResult = "";
$.each(obj, function(i, item) {
var res = "<tr><td>" + item.ID + "</td><td>" + item.mobile + "</td><td>" + item.feedback + "</td><td></tr>";
console.log('res:' + res);
finalResult += res;
});
$('body').append(finalResult)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
see this code
var jsonobj = '[{"ID":"246","mobile":"samsung","feedback":"feedback goes here"},{"ID":"1485","mobile":"Moto","feedback":"feedback goes here"},{"ID":"6982","mobile":"iPhone","feedback":"feedback goes here"}]';
obj = JSON.parse(jsonobj);
alert(obj);
$.each(obj, function (index, item) {
$('<tr/>')
.append('<td>' + item.ID + '</td><td>' + item.mobile + '</td><td>' + item.feedback + '</td><td>')
.appendTo('table');
});
fiddle:http://jsfiddle.net/21wrqrfb/

Categories

Resources