AngularJS: Object manipulation: flattening object in js - javascript

I have an object received in response from backend, and would like to extract elements of object and attach them to scope to make it available in the View.
Following is the structure of the object:
{
"Name": {
"S": "Jon Snow"
},
"Location": {
"S": "Winterfell"
},
"Details": {
"M": {
"Parents": {
"M": {
"mother": {
"S": "Lynna Stark"
}
}
},
"Dog": {
"N": "Ghost Snow"
}
}
}
}
Since I have received it from backend, I don't know what kind of object is this, and I want to convert it to a plain JSON object which should be looking something like this:
{
"Name": "Jon Snow",
"Location": "Winterfell",
"Details": {
"Parents": {
"mother": "Lynna Stark"
},
"Dog": "Ghost Snow"
}
}
Help is appreciated, as I am a beginner in AngularJS and also It would be good if someone elaborates what kind of Object did I receive? Thanks in advance.
Update 1:
Thanks for the responses. Now I have got the idea. Now the question is how to I flatten the object by one level? And If I do flatten does it tamper the original response as it is received from the backend, it may be different every time.

const data = {
"Name": {
"S": "Jon Snow"
},
"Location": {
"S": "Winterfell"
},
"Details": {
"M": {
"Parents": {
"M": {
"mother": {
"S": "Lynna Stark"
}
}
},
"Dog": {
"N": "Ghost Snow"
}
}
}
}
const flatten = (data) =>{
if(typeof data === "string") return data;
for(let key in data){
for(let deep in data[key]){
if(deep.length === 1){
const temp = data[key]
data[key] = flatten(temp[deep])
}
}
}
return data;
}
console.log( JSON.stringify(flatten(data), null, "\t"))
JS bin

Related

How to parse complex nested JSON data in NodeJS

I'm having kind of complex nested JSON in my dynamoDB, I want to extract this Filter object and its values. For example, if Type is macBook return the Filter object and its value PRO and AIR. Please find my code below and JSON input - I'm struggling to parse these value in NodeJS - could someone please help me - how to get the Filter Object?
JSON
{
"ProductType": {
"S": "Apple"
},
"Type": {
"M": {
"iPhone": {
"M": {
"Filter": {
"M": {
"model": {
"SS": [
"X", "XS"
]
}
}
}
}
},
"macBook": {
"M": {
"Filter": {
"M": {
"model": {
"SS": [
"PRO", "AIR"
]
}
}
}
}
}
}
}
}
product.js
const AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB({
region: process.env.AWS_REGION,
});
const getModel = function (productType) {
return new Promise((resolve, reject) => {
var params = {
Key: {
"ProductType": {
S: productType
}
},
TableName: 'product'
};
dynamodb.getItem(params, function (err, data) {
if (err) reject(err, err.stack);
else {
console.log("data: " + Object.keys(data));
let product = data.Item.ProductType.S;
let filterModel = data.Item.Type.M
console.log(filterModel);
}
});
});
}
getModel('Apple')
Any help would be much appreciated
You need to use Object.values to get the values of iPhone and macbook objects, then inside you can use flatMap to find the Filter whose has PRO", "AIR" properties.
const data ={
"ProductType": {
"S": "Apple"
},
"Type": {
"M": {
"iPhone": {
"M": {
"Filter": {
"M": {
"model": {
"SS": [
"X", "XS"
]
}
}
}
}
},
"macBook": {
"M": {
"Filter": {
"M": {
"model": {
"SS": [
"PRO", "AIR"
]
}
}
}
}
}
}
}
}
const result = Object.values(data.Type.M).flatMap((item) => {
const SS = item.M.Filter.M.model.SS
return SS.includes('PRO') && SS.includes('AIR') ? [{ Filter: item.M.Filter.M }] : []
}, [])
console.log(result)

how to retrieve a dictionary's / objects' key value pair in nested dictionary in javascript?

I am trying to make a flashcard application to try and simplify data.
I think that this isn't a very difficult doubt but I am unable to find an answer from google.
I want only the key url and the value to be shown from the nested dictionary
I want to display the route in the form of a arrow map like: abcd->cd->d->url:value
my data ex:
abcd = {
"ab": {
"a": {
"country": "",
"url": ""
},
"b": {
"country": "",
"url": ""
}
},
"cd": {
"c": {
"country": "",
"url": ""
},
"d": {
"country": "",
"url": "value"
}
}
You can use the code given below which works for this object only ...
Note that there are a lot of better ways you can approach this .. this is a simple enough one
let abcd = {
"ab": {
"a": {
"country": "",
"url": "fff"
},
"b": {
"country": "",
"url": "fff"
}
},
"cd": {
"c": {
"country": "",
"url": "ddd"
},
"d": {
"country": "",
"url": "value"
}
}
}
function getKeyValue(obj){
const result = []
for(let prop in obj){
if(typeof obj[prop] === "object"){
for(let pr in obj[prop]){
result.push(`${prop}->${pr}->url->${obj[prop][pr].url }`)
}
}
}
return result
}
console.log(getKeyValue(abcd))

How do I display json data with keys inside key in JavaScript?

I get data from an api, and this data contains one key, that last contains multiple keys, This is my example :
{
"status": 0,
"location": "Casablanca [Doukkala-Abda;Morocco]",
"day": {
"1": {
"date": "20200807",
"name": "Friday",
"month": "", ...
The parent key is the day
The child keys are 1, 2, 3 ...etc, they contains data
I tried to use console.log(data['day']['1']) and console.log(data.day['1']) but I got this error :
Cannot read property '1' of undefined
How do I read this properly ?
Just use the array form when the index is an interger, such as:
let data = {
"day": {
"1": {
"date" : "20200807"
}
}
}
console.log("data:", data);
console.log('data.day["1"]:', data.day["1"]);
console.log('data.day["1"].date:', data.day["1"].date);
You might want to remove the quotes like: data.day[1] instead of data.day['1']
var data =
{
"status": 0,
"location": "Casablanca [Doukkala-Abda;Morocco]",
"day": {
"1": {
"date": "20200807",
"name": "Friday",
"month": ""
},
"2": {
"date": "20200801",
"name": "test",
"month": ""
}
}
}
console.log(data.day[1]);
I assume the issue is that you need to parse your API response with JSON.parse() first, like:
let rawDataFromApi = '{"status":0,"location":"Casablanca [Doukkala-Abda;Morocco]","day":{"1":{"date":"20200807","name":"Friday","month":""}}}'
let data = JSON.parse(rawDataFromApi)
console.log(data['day']['1'])
. operator can be used to get the data.the data is a object so that [] will not be a good idea.
use day.1.date to get the data
Try this.
let data = {
"day": {
"1": {
"date" : "202008071"
}
}
}
let data2 = {
"day": {
"2": {
"date" : "202008072"
}
}
}
let data3 = {
"day": {
"third": {
"date" : "202008073"
}
}
}
console.log(data.day["1"].date);
console.log(data2.day["2"].date);
console.log(data3.day["third"].date);

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])
}

searching for repeated properties in objects in an associative array

I need to find out if one user appears more than once in the associative array (and then sum the value of the same tasks). How do I do that in javaScript?
{
"Items": [
{
"Date": {
"N": "1439883817221"
},
"UserName": {
"S": "user1"
},
"task1": {
"N": "9"
}
},
{
"Date": {
"N": "1439892361108"
},
"task2": {
"N": "3"
},
"UserName": {
"S": "user2"
}
},
{
"Date": {
"N": "1439904242126"
},
"UserName": {
"S": "user1"
},
"task2": {
"N": "2"
}
}
}}
Try this:
var uniqueNames = [];
var nonUniqueNames = [];
$.each( list.Items, function(i, item ) {
if(uniqueNames.indexOf(item.UserName.S) != -1 ){
nonUniqueNames.push(item.UserName.S);
} else {
uniqueNames.push(item.UserName.S);
}
});
alert(nonUniqueNames);
https://jsfiddle.net/c2co1hck/
As for the same tasks you can figure out the same way to do it.
Please define the same tasks anyway as you have different names and values for it.
Posting some of your code would also be appreciated.
By the way you have an error in your JSON, it should end with
]} not with }}

Categories