I am passing a JSON object and an array to a Javascript function, but the array acts empty when I alert it unless I alert a specific value.
function myFunction(jsonObj, array){
alert(array['item1']['name']); //alerts "item1"
alert(array); // alerts "" (not [object] as I'd expect)
alert(array.join('')); // alerts ""
}
What am I missing?
I'm developing with phonegap on xcode and also using jQuery and Jquery Mobile
Seems like you are using an array with string indexes. That won't work well:
> var array = [];
> array['foo'] = 'bar';
> array.length
0
Use an object instead:
var obj = {};
obj['foo'] = 'bar';
Use arrays only with numeric indexes.
Use JQuery's map function.
You can traverse all items in array or JSON Object.
By the way, add console.log(array) to your code and in chrome web dev env, or in firebug check it's structure.
array can only have number as indexes , so as to use normal array functions like join
But , an associative array would be treated in the same way as a JSON object .
You can do the join in the associative array like this :
var temp=[];
temp['item']='hello ';
temp['item2']='world';
var joinedString="";
for( i in temp ){
console.log(temp[i];
joinedString+=temp[i];
}
alert(joinedString); // Prints hello world
Just use it like a map and use a foreach loop . Normal array functions like join , length and all won't work
Related
This is the array:
{"C8_235550":
{"listing":"aut,C8_235550_220144650654"},
"C8_231252":
{"listing":"aut,C8_231252_220144650654"}}
It was fetched with a GET request from a Firebase database using Google Apps Script.
var optList = {"method" : "get"};
var rsltList = UrlFetchApp.fetch("https://dbName.firebaseio.com/KeyName/.json", optList );
var varUrList = rsltList.getContentText();
Notice the .getContentText() method.
I'm assuming that the array is now just a string of characters? I don't know.
When I loop over the returned data, every single character is getting pushed, and the JavaScript code will not find key/value pairs.
This is the FOR LOOP:
dataObj = The Array Shown At Top of Post;
var val = dataObj;
var out = [];
var someObject = val[0];
for (var i in someObject) {
if (someObject.hasOwnProperty(i)) {
out.push(someObject[i]);
};
};
The output from the for loop looks like this:
{,",C,8,_,2,3,5,5,5,0,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,5,5,5,0,_,2,2,0,1,4,4,6,5,0,6,5,4,",},,,",C,8,_,2,3,1,2,5,2,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,1,2,5,2,_,2,2,0,1,4,4,6,5,0,6,5,4,",},}
I'm wondering if the array got converted to a string, and is no longer recognized as an array, but just a string of characters. But I don't know enough about this to know what is going on. How do I get the value out for the key named listing?
Is this now just a string rather than an array? Do I need to convert it back to something else? JSON? I've tried using different JavaScript array methods on the array, and nothing seems to return what it should if the data was an array.
here is a way to get the elements out of your json string
as stated in the other answers, you should make it an obect again and get its keys and values.
function demo(){
var string='{"C8_235550":{"listing":"aut,C8_235550_220144650654"},"C8_231252":{"listing":"aut,C8_231252_220144650654"}}';
var ob = JSON.parse(string);
for(var propertyName in ob) {
Logger.log('first level key = '+propertyName);
Logger.log('fisrt level values = '+JSON.stringify(ob[propertyName]));
for(var subPropertyName in ob[propertyName]){
Logger.log('second level values = '+ob[propertyName][subPropertyName]);
}
}
}
What you have is an object, not an array. What you need to do is, use the
Object.keys()
method and obtain a list of keys which is the field names in that object. Then you could use a simple for loop to iterate over the keys and do whatever you need to do.
I am looking for a solution to create a single multidimensional associate array in javascript.
What I have: I have a mysql database I am accessing with php and have an array containing all fields (key,value pairs) in a single record. Their are upwards of 30 fields in each record so I am looking for a dynamic solution.
In the html coding, there is a form that is used to update a specific record in the table. I am using a function call on each input to fill a javascript array by key and value. The keys are identical to the keys in the php array.
In the function I am doing a json_encode call on the php array to pull in the "old" data to make it accessible to javascript.
What works: I am able to create a dynamic javascript associate array from the new data coming from the input function calls. I have tested this out using an alert after each call to the function.
What I need: A method to change the javascript array to a multidimensional array, pulling in the old value and adding it to the new array tied to the original key.
This works:
var changes={};
function change(key,value) {
changes[key[value]]=value;
for (key in changes) {
alert('key: '+key+'... value: '+changes[key]);
}
}
this is along the lines of what I am looking for:
var changes={};
function change(key,value) {
var oldInfo = eval(<? echo json_encode($oldInfo); ?>); //this from the php array
changes[key[newValue]]=value;
changes[key[oldValue]]=oldInfo[key];
for (key in changes) {
alert('key: '+key+'... value: '+changes[key[newValue]]);
}
}
Can someone point me in the right direction?
To clarify:
My php array $oldInfo holds the old information from the table, for example:
{fName=>"charles",lName=>"madison", etc.}
The javascript array hold new information:
{fName=>"Charlie",lName=>"Madison", etc.}
I would like a new multidimentional array (PHP) (or object in JavaScript) that would look something like this:
{fName=>{"charles","Charlie"}, lName=>{"madison","Madison"}, etc.}
lName and fName would be the key fields that are synonymous to both the PHP array and the JavaScript object.
It's really unclear what you want, but there are a couple of serious flaws with your logic:
var changes={}; ///this one way of declaring array in javascript
No, it isn't. That's an Object, which is very different from an array.
eval(<? echo json_encode($oldInfo); ?>);
You don't need eval here. The output of json_encode is JSON, which is a subset of JavaScript that can simply be executed.
changes[key[value]]=value;
This is totally wrong, and still a single-dimensional array. Assuming key is an array, all you're doing is inverting the keys/values into a new array. If key looks like this before...
'a' => 1
'b' => 2
'c' => 3
... then changes will look like this after:
1 => 'a'
2 => 'b'
3 => 'c'
For a multidimensional array, you need two keys. You'd write something like changes[key1][key2] = value.
Your variable naming is wrong. You should never see a line that reads like this: key[value]. That's backwards. The key goes between the [], the value goes on the other side of the =. It should read something like array[key] = value.
RE: Your clarification:
This doesn't work: {fName=>{"charles","Charlie"},...}. You're confusing arrays and objects; Arrays use square brackets and implicit numeric keys (["charles", "Charlie"] for example) while Objects can be treated like associative arrays with {key1: "value1", key2: "value2"} syntax.
You want an array, where each key is the name of a property and each value is an array containing the old and new values.
I think what you want is actually quite simple, assuming the "value" you're passing into the function is the new value.
var changes = {};
var oldInfo = <?= json_encode($oldInfo) ?>;
function change(key, value) {
changes[key] = [ oldInfo[key], value ]
}
This :
changes[key[newValue]]
Should be:
changes[key][newValue]
What I need: A method to change the javascript array to a multidimensional array, pulling in the old value and adding it to the new array tied to the original key.
Use aliases for the numeric indices to do this:
var foo = ["Joe","Blow"];
var bar = ["joe","blow"];
var names = {};
foo.fname = foo[0];
bar.fname = bar[0];
foo.lname = foo[1];
bar.lname = bar[1];
names.fname = [foo.fname,bar.fname];
names.lname = [foo.lname,bar.lname];
I am looking for a solution to create a single multidimensional associate array in javascript.
What I have: I have a mysql database I am accessing with php and have an array containing all fields (key,value pairs) in a single record. Their are upwards of 30 fields in each record so I am looking for a dynamic solution.
In the html coding, there is a form that is used to update a specific record in the table. I am using a function call on each input to fill a javascript array by key and value. The keys are identical to the keys in the php array.
In the function I am doing a json_encode call on the php array to pull in the "old" data to make it accessible to javascript.
What works: I am able to create a dynamic javascript associate array from the new data coming from the input function calls. I have tested this out using an alert after each call to the function.
What I need: A method to change the javascript array to a multidimensional array, pulling in the old value and adding it to the new array tied to the original key.
This works:
var changes={};
function change(key,value) {
changes[key[value]]=value;
for (key in changes) {
alert('key: '+key+'... value: '+changes[key]);
}
}
this is along the lines of what I am looking for:
var changes={};
function change(key,value) {
var oldInfo = eval(<? echo json_encode($oldInfo); ?>); //this from the php array
changes[key[newValue]]=value;
changes[key[oldValue]]=oldInfo[key];
for (key in changes) {
alert('key: '+key+'... value: '+changes[key[newValue]]);
}
}
Can someone point me in the right direction?
To clarify:
My php array $oldInfo holds the old information from the table, for example:
{fName=>"charles",lName=>"madison", etc.}
The javascript array hold new information:
{fName=>"Charlie",lName=>"Madison", etc.}
I would like a new multidimentional array (PHP) (or object in JavaScript) that would look something like this:
{fName=>{"charles","Charlie"}, lName=>{"madison","Madison"}, etc.}
lName and fName would be the key fields that are synonymous to both the PHP array and the JavaScript object.
It's really unclear what you want, but there are a couple of serious flaws with your logic:
var changes={}; ///this one way of declaring array in javascript
No, it isn't. That's an Object, which is very different from an array.
eval(<? echo json_encode($oldInfo); ?>);
You don't need eval here. The output of json_encode is JSON, which is a subset of JavaScript that can simply be executed.
changes[key[value]]=value;
This is totally wrong, and still a single-dimensional array. Assuming key is an array, all you're doing is inverting the keys/values into a new array. If key looks like this before...
'a' => 1
'b' => 2
'c' => 3
... then changes will look like this after:
1 => 'a'
2 => 'b'
3 => 'c'
For a multidimensional array, you need two keys. You'd write something like changes[key1][key2] = value.
Your variable naming is wrong. You should never see a line that reads like this: key[value]. That's backwards. The key goes between the [], the value goes on the other side of the =. It should read something like array[key] = value.
RE: Your clarification:
This doesn't work: {fName=>{"charles","Charlie"},...}. You're confusing arrays and objects; Arrays use square brackets and implicit numeric keys (["charles", "Charlie"] for example) while Objects can be treated like associative arrays with {key1: "value1", key2: "value2"} syntax.
You want an array, where each key is the name of a property and each value is an array containing the old and new values.
I think what you want is actually quite simple, assuming the "value" you're passing into the function is the new value.
var changes = {};
var oldInfo = <?= json_encode($oldInfo) ?>;
function change(key, value) {
changes[key] = [ oldInfo[key], value ]
}
This :
changes[key[newValue]]
Should be:
changes[key][newValue]
What I need: A method to change the javascript array to a multidimensional array, pulling in the old value and adding it to the new array tied to the original key.
Use aliases for the numeric indices to do this:
var foo = ["Joe","Blow"];
var bar = ["joe","blow"];
var names = {};
foo.fname = foo[0];
bar.fname = bar[0];
foo.lname = foo[1];
bar.lname = bar[1];
names.fname = [foo.fname,bar.fname];
names.lname = [foo.lname,bar.lname];
I have the following javascript code:
var objectArray = [];
var allInputObjects = [];
var allSelectObjects = [];
var allTextAreaObjects = [];
//following returns 3 objects
allInputObjects = document.getElementById("divPage0").getElementsByTagName("INPUT");
//following returns 1 object
allSelectObjects = document.getElementById("divPage1").getElementsByTagName("SELECT");
//following returns 0 objects
allTextAreaObjects = document.getElementById("divPage2").getElementsByTagName("TEXTAREA");
//and following statement does not work
objectArray = allInputObjects.concat(allSelectObjects);
And my problem is that the last line is throwing an error.
I tried the above code in Firefox and it says allInputObjects.concat is not a function.
Any clues, I believe the script is not treating allInputObjects as an Array!
Any help will be appreciated.
getElementsByTagName returns a NodeList, which is similar to an Array except that it does not support all those prototype functions.
To seamlessly convert such an array-like object into an Array, use:
var arr = Array.prototype.slice.call(somenodelist, 0);
arr will almost be identical, except that it now has the Array prototype functions supported, like concat.
What the function actually does is returning a partial Array containing the elements of somenodelist, to be precise everything from index 0 and after. Obviously, this are just all elements, therefore this is a trick to convert array-like objects into real Arrays.
Why do you think that allSelectObjects is an array?
It is initially assigned to an empty array, sure. But then it's overwritten by the getElementsByTagName call on line 6(ish). Variables in Javascript are not strongly typed, so the initial assignment does not force later assignments to also be arrays.
I suspect you'll have some type of NodeList or similar, rather than an array, in the variable when you invoke the final line. (That's what's returned by the method in Firefox, at least.)
As Andezej has pointed out, you're not dealing with an array here, you're dealing with a kind of node list.
Here's one way you can create an array to work with based on the result of getElementsByTagName
var tags = obj.getElementsByTagName('input');
for (var j=0;j<tags.length;j++) {
resultArray.push(tags[j]);
}
Just another funny way to convert your NodeList to an array:
var tags = obj.getElementsByTagName('input'),
tags2Arr = (
function toArr(i){
return i ? toArr(i-1).concat(tags[i]) : [tags[0]];
}(tags.length-1)
);
Now if you add a method to the Array.prototype:
Array.prototype.clone = function() {
var arr = this;
return (function clone(i){
return i ? clone(i-1).concat(arr[i]) : [arr[0]];
})(this.length-1);
};
You can convert a NodeList to an array, using this oneliner:
Array.prototype.clone.call(obj.getElementsByTagName('input'));
As per what I know, arrays in Javascript is nothing but the combination of methods and objects.
Now my task is to display the values of array (say y_array)
I have used for(x in y_array) and then displayed the value.
In mozilla and in IE its working fine, but in IE it displays the first element of array with index as indexOf and value is indexOf(obj, from) which i dont want.
I tried
if(x!='indexOf') { display the array value ; }
It worked and things were fine but there is extensive use of arrays been displayed and I am looking for some permanent fix rather than this hardcoded one.
Can anyone please help me?
You are not the first mixing up arrays and objects. SO should contain a FAQ for this kind of questions ;)
Let's try to explain things:
An array is a row of values, which can be retrieved using their position in the row. The order of the array values is fixed (and may be reordered).
An object is a variable that contains named properties in the form of key-value pairs. The order of the key-value pairs belonging to an object is arbitrary.
An array looks like: [ 'first', 'second', 'third', ..., 'nth' ]
An object looks like: { first:'firstvalue', second:'secondvalue', ..., nth:'nthvalue' }
The first element of an array is the element with index 0 (so the first position in the row has index value 0). You retrieve it using myArray[0]
An object is unordered, so it has no first element. You retrieve any element from it using myObject.somekey or myObject['somekey'].
For arrays you use a loop iterating through the numbered index until the end of the array is reached:
var i=0, len = myArray.length;
for ( i; i<len; i++ ) {
//do something with >>> myArray[i] <<<
}
For objects you use a loop using the key and the in operator (making sure you are only retrieving user defined properties of the object with the .hasOwnAttribute method):
for ( var key in myObject ){
if (myObject.hasOwnProperty(key)) {
// do something with >>> myObject[key] <<<
}
}
Basically, think of an array as a cupboard with drawers, each containing a value. An object can be imagined as a pile of boxes with stickers on the lid, describing the content of the box. Retrieving something from an object, you ask: is there a box with sticker y in pile x and if so, what's in it? Retrieving something from an array, you ask: please give me the contents of drawer nr x.
Now as to your question: the array you are retrieving values for with a for..in loop contains a user defined method, namely indexOf. Using the object style loop for it, the array is treated as object, and the indexOf key (with value like function(){...} I bet) is shown too. IE That's why it may be better to use a traditional for loop with a numeric index when iterating over arrays.
Why is this only in IE? In modern browsers indexOf is a native method of the Array prototype, and native methods are not shown (unless you loop through their prototype that is). IE < 9 doesn't have a native indexOf method for arrays. Somewhere in the scripting you use the method has been added to the Array prototype as a user defined extension.
Bottom line for your problem: don't use for ... in to loop through the values of an array.
For arrays you should use this for loop:
var y_array = [1,2,3,4];
for (var i = 0; i < y_array.length; i++) {
var value = y_array[i];
// do what you want
alert(i + ': ' + value);
}
For objects (objects are like associative arrays - property: value) use this loop:
var y_array = { prop_1 : "value a", prop_2: "value_2", prop_3: 333 }
for (var key in y_array) {
var value = y_array[key];
// do what you want
alert(key + ': ' + value);
}
if there is no value in your json Object like jsobObj = {}. Then you got the indexOf prototype function in side the empty object in IE < 9. (with value like function(){...} I bet) is shown too.
Your can check a condition in side your for Loop. and skip that indexOf.
if(key =='indexOf'){continue;}
E.g :
var jsonObj = { key_1 : "value a", key_2: "value_2", key_3: 333 }
for (var key in y_array) {
if(key == 'indexOf'){continue;} // check if the array contain indexOf
var value = y_array[key];
// do what you want
alert(key + ': ' + value);
}