JavaScript converting an object to an array - javascript

I've researched for about a day and haven't had any luck. I'm trying to access the object properties to simply add it to a typed class in JavaScript. How can i accomplish this? This is the object im receiving:
And this my code resulting in the following error:
Object.keys(selected).forEach(function (key) {
console.log(selected[key]);
});
Error:
ERROR TypeError: Cannot convert undefined or null to object
Any help is most appreciated as I've come to here as a last resort.
selected looks like this:
Object.keys(selected)... the selected in json string:
{
"selected": [
{
"Id": 4,
"Type": 0,
"Image": "",
"Name": "TestName",
"Roles": "TestRole",
"Facility": "TestFacil"
}
]
}

The variable selected is an array, you can try this:
selected.forEach(
item=>
Object.keys(item).forEach(function (key) {
console.log(item[key]);
})
)
It could also be:
selected.selected.forEach(
In your question it's not clear what the name is of the value you are logging the json string of.

let data = {
"selected": [
{
"Id": 4,
"Type": 0,
"Image": "",
"Name": "TestName",
"Roles": "TestRole",
"Facility": "TestFacil"
}
]
}
let arr = [];
for (var key in data) {
arr.push(data[key]);
}
console.log(arr)
or you can use that if you wanna convert the whole object to arrays of arrays
let data = {
"selected": [
{
"Id": 4,
"Type": 0,
"Image": "",
"Name": "TestName",
"Roles": "TestRole",
"Facility": "TestFacil"
}
]
}
var arr = [];
var i =0;
for( var key in data){
var innerArr = [key];
arr.push(innerArr)
for(var values in data[key]){
for(var keys in data[key][values]){
var innerArr3 = [keys];
innerArr.push(innerArr3)
innerArr3.push(data[key][values][keys])
}
}
}
console.log(arr)

Related

traverse from a specific point in json object and up to find all parents

I got a json object like this
{
"id": 1,
"name": "A",
"nodes": [
{
"id": 2,
"name": "B",
"nodes": [
{
"id": 3,
"name": "C",
"nodes": []
}
]
}
]
}
If I have as input the id of the object, lets take id: 3, how would I scan the whole three find the object with specific id and then scan upwards to the last parent.
So after the scan is done I know that C has parent B and B has parent A, so I can then print that like A-B-C
all based on me knowing the id of object I want to find parents of.
The above object can be of any lenght and can have many nodes and levels. So anyone has any idea how to traverse up the levels to top level if starting at specific level?
edit:
when I try to parse this
let data = [
{
"id": 1,
"name": "name",
"testing": "something",
"nodes": [
{
"id": 11,
"name": "name",
"testing": "something",
"nodes": []
}
]
},
{
"id": 2,
"name": "name",
"testing": "something",
"nodes": []
}
]
to json object by doing JSON.parse(data) I get an error
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
Also tried this
let jsonObject = JSON.stringify($scope.data);
jsonObject = JSON.parse(jsonObject);
createTree(jsonObject, null, nodeData.id)
and get different error:
TypeError: obj.nodes is not iterable
Do a basic DFS scan, add parent property along the way, and climb up when node found.
let jsonParsed = JSON.parse(`
{
"id": 1,
"name": "A",
"nodes": [
{
"id": 2,
"name": "B",
"nodes": [
{
"id": 3,
"name": "C",
"nodes": []
}
]
}
]
}
`)
let arr = []
function climbTree(obj) {
arr.unshift(obj.name)
if (obj.parent) {
climbTree(obj.parent)
}
}
function createTree(obj, parent = null, targetId = null) {
obj.parent = parent
if (targetId === obj.id) {
return climbTree(obj)
}
for (let node of obj.nodes) {
createTree(node, obj, targetId)
}
}
createTree(jsonParsed, null, 3)
console.log(arr.join('-'))

Javascript variable list obj.names is null when only some are null

I am trying to get a list together from an array but some of the fields are null and it seems to be breaking there and returning:
obj.names is null
Here is the code:
My Code
var data = {
"people": [{
"id": "32",
"description": "some description",
"archived": "",
"new": 0,
"names": [{
"name": "name 1",
"translations": null
}, {
"name": "name 2",
"translations": null
}],
}, {
"id": "56",
"description": "some description",
"archived": "",
"new": 0,
"names": [{
"name": "name 3",
"translations": null
}, {
"name": "name 4",
"translations": null
}],
}, {
"id": "99",
"description": "some description",
"archived": "",
"new": 0,
"names": null,
},
]
};
var mainData = [data];
var namesList = [];
for (var i = 0; i < mainData[0].people.length; i++) {
var obj = mainData[0].people[i];
var nme = obj.names.name;
namesList.push(nme);
}
console.log(namesList); //This should have the list of names
<div id="container"></div>
JSFiddle Link
How can I fix this?
names is an array, you need to get the name property from the objects inside the names array.
Replace these lines
var nme = obj.names.name;
namesList.push(nme);
by
if( obj.names )
{
var nme = obj.names.map( function(item){
return item.name;
});
namesList = namesList.concat(nme);
}
map method is used to iterate the array and return the name property of each array item.
I prefer using array methods like map/reduce/forEach.
You end up with something like this:
// we want to loop over the people array, but it's not a 1-to-1 relation, since we want all name in the names array, so we use reduce into new array.
var namesList = data.people.reduce(function( ary, peopleRecord ) {
// We want to concat the names from the names array to our result
return ary.concat(
// but if the names array is null, we have nothing to concat, so check if the names array exists
peopleRecord.names && peopleRecord.names.map(function( nameRecord ) {
return nameRecord.name;
// Or else if the names array doesn't exist, just concat an empty array to the final result.
}) || []
);
}, []);

How to iterate nested json object?

I have a nested JSON Object and i want to iterate that.
JSON Response
{
"specifications": {
"IP6": {
"name": "Devices",
"productSubType": "Device",
"productSpecificationType": "Phones"
}
},
"offers": {
"US-PRE-IPHONE-CASE": {
"path": "productDetails/IP6",
"familyData": {
"0": "Missing Family Level data Should be here"
},
"facets": [],
"type": [],
"offers": {
"US-PRE-HG-PH-IP6": {
"hashDigest": "cf23df2207d99a74fbe169e3eba035e633b65d94",
"offerName": "offerNameString",
"productName": "iPhone 6 Case Mate Naked Tough Case - Clear",
"productOfferings": {
"ratings": "4.5",
"noOfReviews": "2010"
},
"offerStatus": {},
"displayPriority": "100200",
"descriptions": {
"shortDescription": "Iphone Decription ",
"longDescription": "longDescriptionStri6 descriptionng",
"alternativeDescription": "alternativeDescriptionString",
"reprsentativeDescription": ""
},
"specifications": [
"someSpecificationId1"
],
"brand": "Apple",
"productType": "Device",
"productSubType": "Phone",
"offerType": "",
"offerSubType": "",
"compatibility": {},
"classification": [],
"images": {
"thumbanail": {
"imagePath": "http://s.tmocache.com/images/png/products/accessories/SUPM43270/SUPM43270-small.png"
}
},
"equipmentCharacteristics": {},
"offerVariants": {},
"type": "hard-good",
"offers": [],
"family": "IP6",
"pricePoints": {
"withServicePrice16GBNEW": {
"displayPriority": "1001",
"pricingMessage": "device price with service activation",
"price": "34.99",
"discounts": {}
}
},
"dynamicPricingData": {},
"inventoryData": {
"SKUGOLD16GBN": {
"availibility": "Pre-order now!",
"availableTimeline": ""
}
}
}
}
}
}
}
Now as you see there are nested JSON objects in this and I want the value of
productName
shortDescription
imagePath
availibility
What I have tried is
function change(){
var acc = response; //response is JSON Object mentioned above
var accArray = [];
var accArray1 = [];
for (var obj in acc.specifications){
accArray.push(obj);
}
alert(accArray[0]);
for (var obj in accArray[0].offers){
accArray1.push(obj);
}
alert(accArray1[0]);
}
I am able to get the first object the first alert output is
IP6
but when I am trying to iterarte the IP6 object in same way the output is
undefined
I want to fetch all the 4 values as I mentioned above and then put them in an array.
As Grundy pointed out in his comment, obj in your code is the key of properties/items in specifications object. That means 'obj' is just a string.
To get reference to the object, change your code as below:
for(var obj in acc.specifications){
accArray.push(acc.specifications[obj]);
}
For better readability change obj to key
You can use for..in loop and recursion.
function find(obj, fieldName){
if(Array.isArray(obj)){
for(var i=0, len=obj.length;i<len;i++){
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}else{
if(typeof obj !== "object") return {isFind:false};
for(var i in obj){
if(i === fieldName) return {isFind:true, value:obj[i]};
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}
return {isFind:false};
}
this function return object with field isFind for case when available value can be null or undefined
var obj = {
"specifications": {
"IP6": {
"name": "Devices",
"productSubType": "Device",
"productSpecificationType": "Phones"
}
},
"offers": {
"US-PRE-IPHONE-CASE": {
"path": "productDetails/IP6",
"familyData": {
"0": "Missing Family Level data Should be here"
},
"facets": [],
"type": [],
"offers": {
"US-PRE-HG-PH-IP6": {
"hashDigest": "cf23df2207d99a74fbe169e3eba035e633b65d94",
"offerName": "offerNameString",
"productName": "iPhone 6 Case Mate Naked Tough Case - Clear",
"productOfferings": {
"ratings": "4.5",
"noOfReviews": "2010"
},
"offerStatus": {},
"displayPriority": "100200",
"descriptions": {
"shortDescription": "Iphone Decription ",
"longDescription": "longDescriptionStri6 descriptionng",
"alternativeDescription": "alternativeDescriptionString",
"reprsentativeDescription": ""
},
"specifications": [
"someSpecificationId1"
],
"brand": "Apple",
"productType": "Device",
"productSubType": "Phone",
"offerType": "",
"offerSubType": "",
"compatibility": {},
"classification": [],
"images": {
"thumbanail": {
"imagePath": "http://s.tmocache.com/images/png/products/accessories/SUPM43270/SUPM43270-small.png"
}
},
"equipmentCharacteristics": {},
"offerVariants": {},
"type": "hard-good",
"offers": [],
"family": "IP6",
"pricePoints": {
"withServicePrice16GBNEW": {
"displayPriority": "1001",
"pricingMessage": "device price with service activation",
"price": "34.99",
"discounts": {}
}
},
"dynamicPricingData": {},
"inventoryData": {
"SKUGOLD16GBN": {
"availibility": "Pre-order now!",
"availableTimeline": ""
}
}
}
}
}
}
}
function find(obj, fieldName){
if(Array.isArray(obj)){
for(var i=0, len=obj.length;i<len;i++){
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}else{
if(typeof obj !== "object") return {isFind:false};
for(var i in obj){
if(i === fieldName) return {isFind:true, value:obj[i]};
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}
return {isFind:false};
}
var result = ['productName','shortDescription','imagePath','availibility'].map(function(el){ return find(obj,el).value});
document.getElementById('r').innerHTML = JSON.stringify(result,null,2);
<pre id='r'></pre>
Your json code is a complex data binding structure. It same like c# complex data binding. So you need to call the obj by through it call name.
for eg:
var data = {"ex":{"a":{"a1":"a1","a2":"a2"},"b":{"b1":"b1","b2":"b2"}}}
so data is a class and it includes "ex" object
data returns =>Object {ex: Object}
if you need to access "a" or "b" object means , you need to access through the"ex" object.
for eg:
data.ex.a => Object {a1: "a1", a2: "a2"}
in your code
for(var obj in acc.specifications){
accArray.push(obj);
}
obj only push 1st element of acc.sppectification object.
So please try this.
foreach(var obj acc.specification){
arr1.push(acc.specification[obj])
}
foreach (var obj acc.offers){
arr2.push(acc.offers[obj])
}

How can I get the result with underscore.js filter?

Here is the test array:
var test = [
{
"id": 1,
"team": [
{
"name": "Alex",
"age": 27,
"checked": true
},
{
"name": "Bob",
"age": 35,
"checked": false
}
],
"checked": true
},
{
"id": "2",
"team": [
{
"name": "Jack",
"age": 37,
"checked": false
},
{
"name": "Tom",
"age": 29,
"checked": true
}
],
"checked": true
}];
And the result that I want to get is an array like this:
result = ["Alex", "Tom"];
The result array contains all items that the "checked" attribute equals to true in team.
I try to get the result with the underscore.js filter, but I cannot get the correct result.
If you have a better solution, please tell me.
Here is my code:
_.filter(test, function(team) {
_.filter(team, function(worker){
if(worker.checked)
return worker.name;
});});
Here's how you can do it in both underscore and lodash:
Underscore jsfiddle:
var result = _.chain(test).pluck('team').flatten().filter({checked:true}).value();
Lodash jsfiddle:
var result = _(test).pluck('team').flatten().filter({checked:true}).value();
Take the team arrays together, flatten them so you have the nested arrays, filter on the property and the result are the objects containing the name and checked being true. If you want just the names, do another pluck.
Here's an underscorejs version with a shorter filter and just giving back the names:
var result = _.chain(test).pluck('team').flatten().filter('checked').pluck('name').value();
// ["Alex", "Tom"]
You can simply use forEach function to handle this
var test = [...];
var result = [];
test.forEach(function(item) {
item.team.forEach(function(worker) {
if(worker.checked) {
result.push(worker.name);
}
})
})
console.log(result)
//Return ["Alex","Tom"]
One way to use filtering for multidimentional array is by using filter and any.
_.filter(test, function(team) {
return _.any(team.team, function(player) {
return player.checked;
});
});

How to search the specific text in a nested object?

For example, I have a JSON array as follow, I will show it on a treelist ,so that user can select the item.Now there is a feature that allowing the user to search the specific text in the list. And the list is a nested list.I hava bind the JSON array to a treelist using HTML and Javascript. Now I should find a good way to search the specific text, and then return the object that include parent node when I find the text.
var allcategories=
[
{
"name": "shoes",
"subcategories": [
{
"name": "man's shoes",
"subcategories": [
{
"name": "sample name"
},
{
"name": "sample name",
"subcategories": []
}
]
},
{
"name": "woman's shoes",
"subcategories": []
}
]
},
{
"name": "cars",
"subcategories": [
{
"name": "cars1",
"subcategories": [
{
"name": "sample name"
},
{
"name": "sample name",
"subcategories": []
}
]
}
]
}
];
So now I want to use the indexOf() function to search the result. If the search is successful, the program should just return the parent category.Anyone have the same question in developing the codes?
As Bergi suggests, you can use a recursive function:
function getCategory(categories, name) {
var category, result;
for (var i=0, iLen=categories.length; i<iLen; i++) {
category = categories[i];
if (category.name == name) {
return category;
} else if (category.subcategories) {
result = getCategory(category.subcategories, name);
if (result) return result;
}
}
// return undefined if category name not found
}
Note that this will return the first subcategory with a matching name, so the name needs to be unique.
#Leeli - you can use this JS lib; DefiantJS (http://defiantjs.com) with which searches in JSON structures becomes a trivial thing. The lib extends the global object JSON with the method "search". With this method, you can search with XPath expressions and it will retusn an array with the matches (empty array if no matches were found). See the example code below.
Here is a working fiddle:
http://jsfiddle.net/hbi99/wXfE6/
var data = [
{
"name": "shoes",
"subcategories": [
{
"name": "man's shoes",
"subcategories": [
{ "name": "heels" },
{ "name": "loafers" }
]
},
{ "name": "woman's shoes" }
]
},
{
"name": "cars",
"subcategories": {
"name": "cars1",
"subcategories": [
{ "name": "Sedan" },
{ "name": "SUV" }
]
}
}
],
res = JSON.search( data, '//*[name="cars1"]/subcategories' );
console.log( res[0].name );
// Sedan
hi here is a jquery function i wrote. since its a associated list in .net the child list is an empty object when there are no child nodes so i have to check is empty instead of simply looking for it to be null. should be backwards compatible though and work as a solution to this question
function findCategory(categories, categoryId)
{
var ret = null;
$.each(categories, function (e, v) {
if (e === categoryId)
ret = v;
else if (!jQuery.isEmptyObject(v.children))
ret = findCategory(v.children, categoryId);
return !ret; //break out of loop when ret not null
});
return ret;
}

Categories