How can I access this nested array within my JSON object? - javascript

I'm using PHP to return a json_encode()'d array for use in my Javascript code. It's being returned as:
{"parent1[]":["child1","child2","child2"],"parent2[]":["child1"]}
By using the following code, I am able to access parent2 > child1
$.getJSON('myfile.php', function(data)
{
for (var key in data)
{
alert(data[key]);
}
}
However, this doesn't give me access to child1, child2, child, of parent1. Alerting the key by itself shows 'parent1' but when I try to alert it's contents, I get undefined.
I figured it would give me an object/array? How do I access the children of parent1?
data[key][0] ?

The JSON returned should be:
{"parent1":["child1","child2","child2"],"parent2":["child1"]}
then you can access them as:
var data = {"parent1":["child1","child2","child2"],"parent2":["child1"]}
alert(data['parent1'][0]);
alert(data['parent1'][1]);
alert(data['parent1'][2]);

You're only iterating one level into the object, so it's correct that you're only seeing the parents. You'll need to descend into those keys to find the children.
// Generally, avoid the "foreach" form in JavaScript.
for (var i = 0; i < data.length; i++) {
alert(data[i]); // Parent1[], Parent2[], etc
var parent = data[i];
for (var j = 0; j < parent.length; j++) {
alert(parent[j]); // Child1, Child2, etc
}
}
Aside, the [] suffix on Parent keys is okay. It is valid JSON.

you can assign it in a variable as follows:
var = data[key];
and then get the contents of the array by using the size of the array.
Hope that helps.

Related

appendChild() fails when trying to append a value stored in an array

The following code deletes all children of a certain element, besides these listed inside the saved variable.
let rightCol = document.querySelector("#rightCol");
let saved = rightCol.querySelectorAll('._4-u2._3-96._4-u8');
let savedArr = [];
saved.forEach(()=>{
savedArr.push(saved);
});
rightCol.innerHTML = ''; // Delete all children before retrieving "saved" ones.
for (var i = 0; i < savedArr.length; i++) {
rightCol.appendChild(savedArr[i]);
};
The code fails with this error:
TypeError: Argument 1 of Node.appendChild does not implement interface Node.
Why the code fails?
The code you presented have 2 errors:
querySelectorAll should be executed on document.
you are pushing entire array in for each loop.
here is the working copy
let rightCol = document.querySelector("#rightCol");
let saved = document.querySelectorAll('._4-u2._3-96._4-u8');
let savedArr = [];
saved.forEach((s)=> {
savedArr.push(s);
});
rightCol.innerHTML = ''; // Delete all children before retrieving "saved" ones.
for (var i = 0; i < savedArr.length; i++) {
rightCol.appendChild(savedArr[i]);
};
You are pushing your collection array for each element in your selection return instead of the elements
Where your code state .each(()=> on the next line, the argument to push should be this
On each iteration of forEach you are adding the entire saved array to savedArr. You should instead add each item using the parameter passed into the forEach callback.
e.g.
saved.forEach((s)=> {
savedArr.push(s);
});
Not sure why you're copying the array over to another array here though..

How can I access a value in a multidimensional object with unique keys in Javascript?

How can I access the value for name in the object below? Also, does this object have a special name since unique keys (i.e. friend1 and friend2) hold other key/value pairs?
var friends = {
"friend1":{
"name":"ana",
"position":1,
"spouse":"billy"
},
"friend2":{
'name':'keri',
'position':2,
'spouse':'david'
}
};
Please note that this is a simplified version of the project I am working on. I realize there is a better way to hold data for a list of friends– the point to keep in mind is that the key that holds the other key/value pairs is unique.
I have tried this but it obviously does not work (i.e. "undefined"):
for( i = 0; i < Object.keys(friends).length; i++ ) {
var theFriend = [i].name;
alert(theFriend);
}
Here is a fiddle.
for(index in friends ) {
var theFriend =friends[index].name;
alert(theFriend);
}
Maestro please: https://jsfiddle.net/rwoukdpf/
In ES5, use:
for (var index in friends) { // NB: index and name have function scope
var name = friends[index].name;
}
In ES6, use:
for (let friend of friends) { // NB: 'of', not 'in'
let name = friend.name;
}
If you must use a normal for loop, ensure that your loop invariants are not evaluated in each iteration:
var keys = Object.keys(friends);
for (var i = 0, n = keys.length; i < n; ++i) {
var name = friends[i].name;
}
Even then this loop is not recommended, though - it's cheaper to use a single pass of the object with for .. in than to create an array of the keys and then iterate through that. The ES6 for .. of is better still.
Try following
var keys = Object.keys(friends);
for( i = 0; i < keys.length; i++ ) {
var theFriend = friends[keys[i]].name;
alert(theFriend);
}
For reference - https://jsfiddle.net/mu7jaL4h/7/
`[i]`
You've just created a new array and put the value of i in it.
You need to tell JavaScript what object you are accessing the i property of.
friends[Object.keys(friends)[i]].name

how to pass only two properties to a $scope variable

ANGULARJS Question:
I got an array of objects and I need to pass it to my $scope variable. The property that's creating a problem for me in special is the user property
since it holds elements like the name and email it affects the way the filter i set in the HTML is filtering the objects I want to display. The object is a list of notes and I want to be able to filter them by content in the note( title and body text)
I have tried to delete the property user from the object with the code below, but that does not work. $scope.notes still loads that attribute.
Ideally I should be able to pass to $scope.notes only the title and body attributes. Any ideas of how to do that efficiently?
var notes = notesService.notesObjectInService;
for (var i = 0; i < notes.length; i++) {
delete notes[i].user;
};
$scope.notes = notes;
This is the json object passed to notes in the first line.
[{"id":184,
"title":"Mari",
"body":"Mae",
"created_at":"2015-05-09T03:23:04.250Z",
"updated_at":"2015-05-09T03:23:04.250Z",
"user_id":1,
"user":{"id":1,
"email":"vini#vini.com",
"created_at":"2015-04-24T22:49:21.797Z",
"updated_at":"2015-05-09T03:04:27.739Z",
"username":"vinivini"}}]
How about adding this function to your notesService?
function getSummaryNotes() {
var returnValue = [];
for (var i = 0; i < notes.length; i++) {
var note = notes[i];
returnValue.push({title: note.title, body: note.body});
}
return returnValue;
}
Where notes is your array of notes which presumably the service has access to.
Then you can do:
$scope.notes = notesService.getSummaryNotes();

How to iterate over JSON data

The following is my JSON data in a div:
[{"Identifier":"1","Label":"10 Day","Categories":"Standard","UpdatedBy":"Lno","UpdatedAt":"01-02-2013","RefId":"0","ComType":"1","Cs":["944"],"AM":"Error Message","Message":"asdfasdf","Combiner":[{"uniqueID":"1","type":"7","rule":""}]}]
I am accessing it through a JS object:
var myArrayVar=JSON.parse(document.getElementById("populateDT").innerHTML);
I want to iterate over this JS object. The following is my code, but it doesn't access my key/value fields:
for(var i=0; i<=myArrayVar.length;i++){
for(var j=0; j<=myArrayVar.Combiner.length; j++){
var sessionUniqueId= myArrayVar.Combiner[j].uniqueID;
alert(sessionUniqueId);
var sessionType=myArrayVar.Combiner[j].type;
alert(sessionType);
var sessionRule=myArrayVar.Combiner[j].rule;
alert(sessionRule);
}
}
Can anyone suggest a solution?
for (var i = 0; i < myArrayVar.length; i++) {
for (var j = 0; j < myArrayVar[i].Combiner.length; j++) {
var sessionUniqueId = myArrayVar[i].Combiner[j].uniqueID;
alert(sessionUniqueId);
var sessionType = myArrayVar[i].Combiner[j].type;
alert(sessionType);
var sessionRule = myArrayVar[i].Combiner[j].rule;
alert(sessionRule);
}
}
You never use i. You need it to access the current array element, for example:
for(var j=0; j<=myArrayVar[i].Combiner.length; j++){
myArrayVar is your array, myArrayVar[i] is the i-th element in that array and myArrayVar[i].Combiner is the combiner (array) property of the i-th element.
You'll make it yourself a lot easier if you give the current element a name as well. (You probably want to come up with a less generic name such as current though.)
for(var i=0; i<myArrayVar.length;i++){
var current=myArrayVar[i];
for(var j=0; j<current.Combiner.length; j++){
var sessionUniqueId=current.Combiner[j].uniqueID;
alert(sessionUniqueId);
var sessionType=current.Combiner[j].type;
alert(sessionType);
var sessionRule=current.Combiner[j].rule;
alert(sessionRule);
}
}
Also, i cannot equal myArrayVar.length as that index is already out of bounds. Your loop condition should have < instead of <=.
You have an array with one element. That element is in myArrayVar[0] and it is an object. To iterate over the object use a for ... in loop.
var myObj = myArrayVar[0];
for(var key in myObj){
var value = myObj[key];
console.log(key, value);
}
You should also use console.log for debugging. It will show you more information about objects than alert can.
Try using "<" instead of "<=" in the for loops, and "myArrayVar[i].Combiner" instead of "myArrayVar.Combiner".
There are a couple of problems I see. First, your i and j variables go one spot too far. They should be using < instead of <=.
Secondly, you're declaring variables inside the loop. That's fine, but JavaScript isn't block scoped, so you really end up with the same three variables overwriting each other as many times as there are items in the list. Your example data only has one item so you probably won't notice the overwriting problem just yet–but once you have multiple items in the list it could be a problem.

How to parse JSON data when the property name is not known in advance?

Here is my response code in jQuery:
var response = $.parseJSON(response);
for (var i = 0; i < response.groupIds.length; i++) {
console.log(response.groupIds[i], i);
}
Each response.groupIds[i] is of the form {"unknown name":"unknown value"}.
I wish to access both of these bits of data in javascript, how do I accomplish this when I don't know in advance what e.g. unknown name is?
Use Object.keys to retrieve a full list (array) of key names. A polyfill is available here.
var group = response.groupIds[i];
var allPropertyNames = Object.keys(group);
for (var j=0; j<allPropertyNames.length; j++) {
var name = allPropertyNames[j];
var value = group[name];
// Do something
}
Your question's response format contains only one key-value pair. The code can then be reduced to:
var group = response.groupIds[i];
var name = Object.keys(group)[0]; // Get the first item of the list; = key name
var value = group[name];
If you're not interested in the list, use a for-i-in loop with hasOwnProperty. The last method has to be used, to exclude properties which are inherit from the prototype.
for (var name in group) {
if (group.hasOwnProperty(name)) {
var value = group[name];
// Do something
}
}
Use a for..in loop:
for( x in response.groupIds[i]) {
// x is now your unknown key
// response.groupIds[i][x] is the unknown value
}
Since there is only one property of the object, that'll work nicely.

Categories