Parsing out data from json - javascript

Wrecking my head today trying to find out how to loop through and log out the name of each object.
Here is the JSON response:
{
"placeListings": {
"OBJ1": {
"Active": true,
"Name": "place 1"
},
"OBJ2": {
"Active": true,
"Name": "place 2"
},
"OBJ3": {
"Active": true,
"Name": "place 3"
}
}
}
I would like to parse out the "Name" part in a for loop
for (let i = 0; i < res.length; i++) {
console.log("NAME: " + res.placeListings.OBJ1.Name);
}
But I don't know how to iterate through OBJ1/OBJ2/OBJ3 etc..
Any help is welcome!

The placeListings is an object, not an array.
So you need to use the Object.keys method to get the object's keys
const source = {
placeListings: {
OBJ1: {
Active: true,
Name: 'place 1'
},
OBJ2: {
Active: true,
Name: 'place 2'
},
OBJ3: {
Active: true,
Name: 'place 3'
}
}
}
const keys = Object.keys(source.placeListings)
console.log(keys)
for (let i = 0; i < keys.length; i++) {
console.log(source.placeListings[keys[i]])
}

You can simply achieve this with a single line of code by using Object.keys() and Array.forEach() method.
Demo :
const res = {
"placeListings": {
"OBJ1": {
"Active": true,
"Name": "place 1"
},
"OBJ2": {
"Active": true,
"Name": "place 2"
},
"OBJ3": {
"Active": true,
"Name": "place 3"
}
}
};
Object.keys(res.placeListings).forEach(key => console.log(res.placeListings[key].Name));

Related

Nested for loop through json object array does not work

I need to build a new array based on json array (Context) bellow. Unfortunately I never reach the outer Loop after passing by first run. Is there any mistake in code? How can I solve this issue?
Thank you for help.
Context:
"rfqBp": [
{
"rfqBpId": 1041650,
"Contact": [
{
"ID": 1000014,
"SelectedContact": true
},
{
"ID": 1002411,
"SelectedContact": true
},
{
"ID": 1016727,
"SelectedContact": true
},
{
"ID": 1017452,
"SelectedContact": true
}
],
},
{
"rfqBpId": 1052326,
"Contact": [
{
"ID": 1016236,
"SelectedContact": true
},
{
"ID": 1019563,
"SelectedContact": true
}
],
},
{
"rfqBpId": 1056632,
"Contact": [
{
"ID": -1,
"SelectedContact": false
}
],
},
{
"rfqBpId": 1056637,
"Contact": [
{
"ID": 1019875,
"SelectedContact": true
}
],
}
],
script:
$scope.SelectedContacts = function() { //function starts by click on checkbox in html
let selectedContactList = [];
let finalList = [];
$scope.Context.Output = [];
for (let i = 0; i <= $scope.Context.rfqBp.length; i++) {
for (let j = 0; j <= $scope.Context.rfqBp[i].Contact.length; j++) {
if ($scope.Context.rfqBp[i].Contact[j].SelectedContact === true) {
selectedContactList = {
"ID": $scope.Context.rfqBp[i].Contact[j].ID
};
finalList.push(selectedContactList);
} else if ($scope.Context.rfqBp[i].Contact[j].SelectedContact !== true) {
continue;
}
$scope.Context.Output = finalList; //Output works but just for rfqBp[1]
};
};
$scope.Context.Output = finalList; //this part never reached
};
Output:
"Output": [
{
"ID": 1000014
},
{
"ID": 1016727
},
{
"ID": 1017452
}
]
I try to get following:
"Output": [
{
"ID": 1000014
},
{
"ID": 1016727
},
{
"ID": 1017452
},
{
"ID": 1016236
},
{
"ID": 1019563
},
{
"ID": 1019875
}
]
You can use Array.prototype.flatMap() combined with Array.prototype.filter(), Array.prototype.map() and Destructuring assignment:
const rfqBp = [{rfqBpId: 1041650,Contact: [{ID: 1000014,SelectedContact: true,},{ID: 1002411,SelectedContact: true,},{ID: 1016727,SelectedContact: true,},{ID: 1017452,SelectedContact: true,},],},{rfqBpId: 1052326,Contact: [{ID: 1016236,SelectedContact: true,},{ID: 1019563,SelectedContact: true,},],},{rfqBpId: 1056632,Contact: [{ID: -1,SelectedContact: false,},],},{rfqBpId: 1056637,Contact: [{ID: 1019875,SelectedContact: true,},],},]
const result = rfqBp
.flatMap(({ Contact }) => Contact
.filter(({ ID }) => ID > 0) // Filter to exclude negative `ID`s
.map(({ ID }) => ({ ID }))
)
console.log(result)

Normalize JSON to a custom schema

I have an array of objects with the following format
var arr = [
{
"productId": "123456",
"productName": "Test Product 1",
"description": [
"This is delicious",
"Suitable for vegetarian"
],
"attributes": {
"internalId": "091283"
"category": "Dairy"
},
"order": 1
}
];
And I am trying to map into something like below
[
[{
{
"name": "productId",
"value": "123456"
},
{
"name": "productName",
"value": "Test Product 1"
},
{
"name": "description",
"value": ["This is delicious", "Suitable for vegetarian"]
},
{
"name": "attributes",
"value": {
{
"name": "internalId",
"value": "091283"
},
{
"name": "category",
"value": "Dairy"
}
}
},
{
"name": "order",
"value": 1
}
}]
]
I tried mapping simple properties before going further and now stuck at getting only the last property of each object in the loop.
Suppose I don't know what are the format of incoming data and how can I normalize the JSON object to the format I want?
normalizeJson = (array) => {
for(i = 0; i < array.length; i++){
normalizedJson[i] = {};
Object.keys(array[i]).forEach(key => {
if (array[i][key] && typeof array[i][key] === "object") {
// normalizeJson(obj[key]);
// console.log(key + ' is object');
return;
} else {
o = {};
o["name"] = key;
o["value"] = array[i][key];
normalizedJson[i] = o;
// normalizedJson[i]["name"] = key;
// normalizedJson[i].value = array[i][key];
// console.log(key);
return;
}
});
}
console.log(normalizedJson);
};
Or is there any library I can use in order to achieve this?
Try this
var obj = [
{
productId: "123456",
productName: "Test Product 1",
description: ["This is delicious", "Suitable for vegetarian"],
attributes: {
internalId: "091283",
category: "Dairy",
},
order: 1,
},
];
function normalizeObject(obj) {
var result = [];
if (Array.isArray(obj)) {
for (let i of obj) {
result.push(normalizeObject(i));
}
} else if (typeof obj == "object") {
for (let i of Object.keys(obj)) {
result.push({ name: i, value: normalizeObject(obj[i]) });
}
} else {
return obj;
}
return result;
}
console.log(JSON.stringify(normalizeObject(obj), null, 2));
This looping method called recursion. Which is loop by calling function itself.

Not getting whole flattened javascript object structure

I have a nested object that I wish to retrieve certain key/value pairs from. For these to be retrieved they must have a value for each key.
I'm close, but I'm not getting any of the nested objects' key/value pairs.
I have created this fiddle
Here's the function I have at present:
function getKeysVals(obj, keys, recurse = false)
{
let addToOutput = true;
let out = [];
let cnt = 0;
obj.map
(
(thisObj) =>
{
let newObj = {}; // Temp holder for new object that gets added to output.
// Loop through the requested keys, adding them to the new object:
for( i in keys)
{
// Check that this key has a value:
if(!thisObj[keys[i]])
{
addToOutput = false;
break;
}
else
{
newObj[keys[i]] = thisObj[keys[i]];
}
}
// Ensure we have values for ALL the requested keys in this object:
if( addToOutput ) out.push(newObj);
// Go round again if this object has the specified recurse object:
if( thisObj[recurse] )
{
getKeysVals(thisObj[recurse], keys, recurse)
}
}
);
return out
}
When I call it with result = getKeysVals(nodes[0].nodes, ['id', 'text', 'filePath'], 'nodes'); I expect to get a new array with:
[
{ id: 1526297185466,​​​​​ text: 'test part a',​​​​​ filePath: 'test part a-1526297185451.CSV' },
{ id: 1526297202132,​​​​​ text: 'test part B',​​​​​ filePath: 'test part B-1526297202118.CSV' },​​​​​
{ id: 1526297209980,​​​​​ text: 'Test Part C',​​​​​ filePath: 'Test Part C-1526297209966.CSV' }
]
But I only get:
[{ id: 1526297185466,​​​​​ text: 'test part a',​​​​​ filePath: 'test part a-1526297185451.CSV' }]
The whole object:
[{
"id": 1526297177970,
"text": "k",
"nodes": [
{
"id": 1526297185466,
"tags": [1],
"text": "test part a",
"state": { "checked": true, "expanded": true },
"filePath": "test part a-1526297185451.CSV"
},
{
"id": 1526297195199,
"tags": [1],
"text": "New Product Set",
"nodes": [
{
"id": 1526297202132,
"tags": [1],
"text": "test part B",
"state": { "checked": true, "expanded": true },
"filePath": "test part B-1526297202118.CSV"
},
{
"id": 1526297209980,
"tags": [1],
"text": "Test Part C",
"state": { "checked": true, "expanded": true },
"filePath": "Test Part C-1526297209966.CSV"
}
],
"state": { "checked": true }
}
],
"state": { "checked": true }
}]
If you call
getKeysVals(thisObj[recurse], keys, recurse)
This will create a new out and return that, so you may add that to the current out:
out.push(...getKeysVals(thisObj[recurse], keys, recurse));

how to make array of objects in javascript using different objects?

I am trying to make a array which have objects .Actually I need to push object in array but before I have some conditions
I have a array(a is array of objects) .I need to first remove all objects which have property "hidden": true, .I am able to do that like this
I have another b(b is is array of objects).in which I need to collect values from that using parameter fieldNameOrPath .Those value which are deleted from first array which have hidden :true need not to consider in second array .Not to check fieldNameOrPath.Or we can also delete those are deleted from first array using fieldNameOrPath
I trying to fetch values try to get expected result I fail to get
var deletedfieldNameOrPath=[ ];
for (var i = 0; i < a.length; i++) {
if (a[i].hidden) {
deletedfieldNameOrPath.push(a[i].fieldNameOrPath)
delete a[i]
}
}
console.log(a);
console.log(deletedfieldNameOrPath);
var objectarray = []
for (var i = 0; i < b.length; i++) {
for (var k = 0; k < b[i].columns.length; k++) {
var obj = {};
if (deletedfieldNameOrPath.indexOf(b[i].columns.fieldNameOrPath) == -1) {
obj.b[i].columns.fieldNameOrPath = b[i].columns.value;
}
objectarray.push(obj)
}
}
Expected array
[{
Type__c: "pqr",
akritiv__So_Number__c: "a"
}, {
Type__c: "Invoice",
akritiv__So_Number__c: "-"
}, {
Type__c: "inc",
akritiv__So_Number__c: "c"
}, ]
here is fiddle
http://jsfiddle.net/93m4wbh1/
You are pretty close to what you want i think.
I did some minor changes:
First i used splice instead of delete to make sure the object is
removed from the array instead of leaving an empty record.
Then i made sure the object is created and pushed for each column, not each record in each column.
And at last I fixed a little bug preventing
the values to be added to your object, using the [] (like on arrays).
var a = [{
"hidden": true,
"fieldNameOrPath": "Name",
}, {
"hidden": true,
"fieldNameOrPath": "akritiv__Account__r.Name",
}, {
"hidden": false,
"fieldNameOrPath": "Type__c",
}, {
"hidden": false,
"fieldNameOrPath": "akritiv__So_Number__c",
}];
var deletedfieldNameOrPath = [];
var collectNameOrPath = [];
for (var i = 0; i < a.length; i) {
if (a[i].hidden) {
deletedfieldNameOrPath.push(a[i].fieldNameOrPath)
a.splice(i, 1);
continue;
} else {
collectNameOrPath.push(a[i].fieldNameOrPath);
}
i ++;
}
console.log(a);
console.log(deletedfieldNameOrPath);
[{
Type__c: "pqr",
akritiv__So_Number__c: "a"
}, {
Type__c: "Invoice",
akritiv__So_Number__c: "-"
}, {
Type__c: "inc",
akritiv__So_Number__c: "c"
},
]
var b = [{
"columns": [{
"value": "a0RK0000002l3AB",
"fieldNameOrPath": "Name"
}, {
"value": "Sun Life Financial",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "pqr",
"fieldNameOrPath": "Type__c"
}, {
"value": "a",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}, {
"columns": [{
"value": "a0RK0000002l3ac",
"fieldNameOrPath": "Name"
}, {
"value": "Scottish Power",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "Invoice",
"fieldNameOrPath": "Type__c"
}, {
"value": "-",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}, {
"columns": [{
"value": "a0RK0000002l3aC",
"fieldNameOrPath": "Name"
}, {
"value": "FirstEnergy",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "inc",
"fieldNameOrPath": "Type__c"
}, {
"value": "c",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}]
var objectarray = []
for (var i = 0; i < b.length; i++) {
var obj = {};
for (var k = 0; k < b[i].columns.length; k++) {
if (deletedfieldNameOrPath.indexOf(b[i].columns[k].fieldNameOrPath) == -1) {
obj[b[i].columns[k].fieldNameOrPath] = b[i].columns[k].value;
}
}
objectarray.push(obj)
}
console.log(objectarray);
There is no reason to delete elements from the array.
Try this.
var a = [{
"hidden": true,
"fieldNameOrPath": "Name",
}, {
"hidden": true,
"fieldNameOrPath": "akritiv__Account__r.Name",
}, {
"hidden": false,
"fieldNameOrPath": "Type__c",
}, {
"hidden": false,
"fieldNameOrPath": "akritiv__So_Number__c",
}];
var collectNameOrPath =
a.filter(function(o) { return !o.hidden })
.map(function(o) { return o.fieldNameOrPath });
console.log(collectNameOrPath);
var b = [{
"columns": [{
"value": "a0RK0000002l3AB",
"fieldNameOrPath": "Name"
}, {
"value": "Sun Life Financial",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "pqr",
"fieldNameOrPath": "Type__c"
}, {
"value": "a",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}, {
"columns": [{
"value": "a0RK0000002l3ac",
"fieldNameOrPath": "Name"
}, {
"value": "Scottish Power",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "Invoice",
"fieldNameOrPath": "Type__c"
}, {
"value": "-",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}, {
"columns": [{
"value": "a0RK0000002l3aC",
"fieldNameOrPath": "Name"
}, {
"value": "FirstEnergy",
"fieldNameOrPath": "akritiv__Account__r.Name"
}, {
"value": "inc",
"fieldNameOrPath": "Type__c"
}, {
"value": "c",
"fieldNameOrPath": "akritiv__So_Number__c"
}]
}]
var nameOrPathValues = b.map(function(o) {
var result = {};
o.columns.forEach(function(c) {
result[c.fieldNameOrPath] = c.value;
});
return result;
});
console.log(nameOrPathValues);
var objectarray = nameOrPathValues.map(function(o) {
var result = {};
collectNameOrPath.forEach(function(name) {
result[name] = o[name];
});
return result;
});
console.log(objectarray);

JS string counter

I want this code to count the number of times that category and message are in the bottom string, regardles of the different id number. The code just gives me the last one.
It is quite messy, sry. Thanks for your help.
Kind regards.
counter = function() {
var value = $('#text').val();
if (value.length == 0) {
$('#wordCount').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
};
$(document).ready(function() {
var obj = {"data" : {
"from": {
"category": "cat1",
"id": 1,
"message": "WIZ1"
},
"from": {
"category": "cat2",
"id": 2,
"message": "WIZ2"
},
"from": {
"category": "cat3",
"id": 3,
"message": "WIZ3"
},
"from": {
"category": "cat4",
"id": 4,
"message": "WIZ3"
},
}
};
$.each(obj, function() {
$.each(this, function(name, value) {
$("#result").append(name + '=' + value.category);
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result">Words: <span id="wordCount">0</span>
<br/>
</div>
You have a single object with the "from" property being overwritten 4 times. It looks like what you wanted was to instead have an array, like the example below.
I also changed the code to actually capture the categories and messages, like the description in your post, after the loops those objects will have the count by message and count by category.
counter = function() {
var value = $('#text').val();
if (value.length == 0) {
$('#wordCount').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
};
$(document).ready(function() {
var obj = {"data" : [
{
"category": "cat1",
"id": 1,
"message": "WIZ1"
},
{
"category": "cat2",
"id": 2,
"message": "WIZ2"
},
{
"category": "cat3",
"id": 3,
"message": "WIZ3"
},
{
"category": "cat4",
"id": 4,
"message": "WIZ3"
},
]
};
var categories = {};
var messages = {}
$.each(obj, function() {
$.each(this, function(name, value) {
if (!categories[value.category]) categories[value.category] = 0;
categories[value.category] += 1;
if (!messages[value.message]) messages[value.message] = 0;
messages[value.message] += 1;
$("#result").append(name + '=' + value.category);
});
});
console.log(categories);
console.log(messages);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result">Words: <span id="wordCount">0</span>
<br/>
</div>
Each of the items in the JS object have the same key ('from').
That's causing each one to overwrite the previous, which is why it's only finding the last one.
{
"data": {
"from1": {
"category": "cat1",
"id": 1,
"message": "WIZ1"
},
"from2": {
"category": "cat2",
"id": 2,
"message": "WIZ2"
},
"from3": {
"category": "cat3",
"id": 3,
"message": "WIZ3"
},
"from4": {
"category": "cat4",
"id": 4,
"message": "WIZ3"
}
}
}
This will allow it to iterate through each item as there will now be four items present.

Categories