How to make unique array in javascript - javascript

I have an array of objects.
I need to get an array with a unique website name with the newest date.
Sample data
"data" : [
{
"position" : 2,
"website" : "abc.com",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 3,
"website" : "qwe.com",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 1,
"website" : "qwe.com",
"owned" : false,
"date" : "2020-04-06",
"dateTime" : ISODate("2020-04-06T00:00:00.000Z")
},
{
"position" : 6,
"website" : "xyz.agency",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 4,
"website" : "opq.com",
"owned" : true,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 2,
"website" : "opq.com",
"owned" : true,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 4,
"website" : "opq.com",
"owned" : true,
"date" : "2020-04-01",
"dateTime" : ISODate("2020-04-01T00:00:00.000Z")
}
]
Based on DateTime, position, and website. Need a MongoDB query or Javascript code.
(It's fine with DateTime and website. But getting stuck with position)
(Extracting the object from which have the highest date and unique website name with top position)
Expected response
"data" : [
{
"position" : 2,
"website" : "abc.com",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 3,
"website" : "qwe.com",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 6,
"website" : "xyz.agency",
"owned" : false,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
"position" : 2,
"website" : "opq.com",
"owned" : true,
"date" : "2020-05-06",
"dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}
],

Using the below utility you can achieve the required output in javascript. Hope this will help
const getUniqueWebsites = data => {
return data.reduce((result, d) => {
if(result[d.website]) {
if(new Date(result[d.website].dateTime).getTime() < new Date(d.dateTime).getTime()){
result[d.website] = d;
}
else if(new Date(result[d.website].dateTime).getTime() === new Date(d.dateTime).getTime() &&
(result[d.website].position) > d.position){
result[d.website] = d;
}
} else {
result[d.website] = d;
}
return result;
},{})
}
let data = [
{
"position": 2,
"website": "abc.com",
"owned": false,
"date": "2020-05-06",
"dateTime": "2020-05-06T00:00:00.000Z"
},
{
"position": 3,
"website": "qwe.com",
"owned": false,
"date": "2020-05-06",
"dateTime": "2020-05-06T00:00:00.000Z"
},
{
"position": 1,
"website": "qwe.com",
"owned": false,
"date": "2020-04-06",
"dateTime": "2020-04-06T00:00:00.000Z"
},
{
"position": 6,
"website": "xyz.agency",
"owned": false,
"date": "2020-05-06",
"dateTime": "2020-05-06T00:00:00.000Z"
},
{
"position": 4,
"website": "opq.com",
"owned": true,
"date": "2020-05-06",
"dateTime": "2020-05-06T00:00:00.000Z"
},
{
"position": 2,
"website": "opq.com",
"owned": true,
"date": "2020-05-06",
"dateTime": "2020-05-06T00:00:00.000Z"
},
{
"position": 4,
"website": "opq.com",
"owned": true,
"date": "2020-04-01",
"dateTime": "2020-04-01T00:00:00.000Z"
}
]
let result = getUniqueWebsites(data)
console.log(Object.values(result))

If you want to do from JS level (warning! low performance):
var maxDate = {}; // temporary variable to store latest date of a website
var websites = data
.map(entry => {
if ((maxDate[entry.website] || 0) < entry.dateTime.getTime()) {
maxDate[entry.website] = entry.dateTime.getTime();
}
return entry;
})
.filter(entry => {
return maxDate[entry.website] === entry.dateTime.getTime();
});
If you want to do that with mongodb query: Select Max() with "group by" in mongodb

Related

how to update document using aggregation

I have complex document I try to update using aggregate but it's only making copy when I use $out it's remove all other document I want to concate all other file to this and update........................................................................................................................................................................................................................................................................................................................................................................................................
db.getDb().collection(coll.seat).aggregate( [
{
'$unwind': {
'path': '$show_seats'
}
}, {
'$unwind': {
'path': '$show_seats.showByDate.shows'
}
}, {
'$unwind': {
'path': '$show_seats.showByDate.shows.showSeats'
}
}, {
'$unwind': {
'path': '$show_seats.showByDate.shows.showSeats'
}
}, {
'$unwind': {
'path': '$show_seats.showByDate.shows.showSeats.seat_details'
}
}, {
'$unwind': {
'path': '$show_seats.showByDate.shows.showSeats.seat_details.values'
}
}, {
'$match': {
'show_seats.showByDate.shows.showSeats.seat_details.values._id': ObjectId('62af61b72609bb5c0b664e7e')
}
}, {
'$addFields': {
'show_seats.showByDate.shows.showSeats.seat_details.values.seat_status': true
}
},
{
$out: 'shows'
}
])
this is my mongo db data look like
{
"_id" : ObjectId("62a43ac2d7213c7233cd1dee"),
"totalShowByDay" : "2",
"totalShowDays" : 4,
"movieId" : ObjectId("62953ba3cb6ae625ec9433e6"),
"screenId" : ObjectId("6293b9638dde2d92658d5513"),
"createdAt" : 1654930114438,
"showId" : ObjectId("62a43ac2d7213c7233cd14ed"),
"show_seats" : [
{
"showByDate" : {
"ShowDate" : "2022-06-11",
"shows" : [
{
"showTime" : "2022-06-11T10:00",
"showSeats" : [
[
{
"category" : "CLASSIC",
"seat_details" : [
{
"key" : "A",
"values" : [
{
"_id" : ObjectId("62a43ac2d7213c7233cd14ee"),
"seat_number" : "1",
"tag_name" : "A",
"seat_status" : false,
"user_id" : false,
"price" : "140",
"seats_category" : "CLASSIC",
"show_time" : "2022-06-11T10:00"
},
,
{
"_id" : ObjectId("62a43ac2d7213c7233cd14ef"),
"seat_number" : "2",
"tag_name" : "A",
"seat_status" : false,
"user_id" : false,
"price" : "140",
"seats_category" : "CLASSIC",
"show_time" : "2022-06-11T10:00"
},
{
"_id" : ObjectId("62a43ac2d7213c7233cd14f0"),
"seat_number" : "3",
"tag_name" : "A",
"seat_status" : false,
"user_id" : false,
"price" : "140",
"seats_category" : "CLASSIC",
"show_time" : "2022-06-11T10:00",,
{
"_id" : ObjectId("62a43ac2d7213c7233cd14ef"),
"seat_number" : "2",
"tag_name" : "A",
"seat_status" : false,
"user_id" : false,
"price" : "140",
"seats_category" : "CLASSIC",
"show_time" : "2022-06-11T10:00"
},
{
"_id" : ObjectId("62a43ac2d7213c7233cd14f0"),
"seat_number" : "3",
"tag_name" : "A",
"seat_status" : false,
"user_id" : false,
"price" : "140",
"seats_category" : "CLASSIC",
"show_time" : "2022-06-11T10:00"
}

How to group by sub documents and get unique value of value field?

This is my database collection:
{"productId" : 1,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 2,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 3,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 4,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
}
Now I want to send the data of only the attribute where isVariation is not 0. Also I want to send the variant values of each attribute where isComplete =1. Hence the result should look like this
result : [{
"id": 3,
"name": "Capacity",
"value": [
"500 GB",
"1 TB"
]
}, {
"id": 4,
"name": "Form Factor",
"value": [
"5 inch"
]
}]
The above result does not have value of 2.5 inch as the isComplete is 0 for this document. Can anyone help me with the query
$match isComplete is 1
$project to show required fields
$unwind deconstruct attributeSet array
$match attributeSet.isVariation is not 0
$group by attributeSet.id and get first name and get unique value using $addToSet
db.collection.aggregate([
{ $match: { isComplete: 1 } },
{
$project: {
_id: 0,
attributeSet: 1
}
},
{ $unwind: "$attributeSet" },
{ $match: { "attributeSet.isVariation": { $ne: 0 } } },
{
$group: {
_id: "$attributeSet.id",
name: { $first: "$attributeSet.name" },
value: { $addToSet: "$attributeSet.value" }
}
}
])
Playground
The $project stage is not required in your query, i have added because this will optimize your query performance.

Nested map function returning array of objects with index as key value?

I'm trying to reformat some data from an API and I'm having trouble getting it the way I need. I need everything to be flattened and my second map function (attMap) is returning them with the an index as the key value?
var attMap = products.items.map( x => x.custom_attributes.map( y => ( {[y.attribute_code]: y.value} )));
You can see my first map function (prodMap) works properly.
var prodMap = products.items.map( x => ({ name: x.name, sku: x.sku }));
You can see the result in this image after merging them:
newArray = [];
prodMap.forEach((itm, i)=> {
newArray.push(Object.assign({}, itm, attMap[i]));
});
Fiddle: https://jsfiddle.net/dkx9qewt/
I'm not the best programmer but is my attMap map function returning an array of objects because it's nested? Is that the issue?
Edit: The output I'm looking for is something like:
["Description":"Product Description","Short Description":"shortdescription","Surname":"surname","Length":"6","Tip Configuration":"Blunt","Instrument Type":"Hemostatic Forceps","Curvature":"Curved","Working Surface Style":"Serrated with Longitudinal Groove","Handle":"Finger Rings","Material":"Stainless Steel","Disposable or Reusable":"Reusable",Sterile or Non-Sterile":"Non-Sterile","Latex or Latex-Free":"Latex-Free","Grade":"Premium OR-Grade","name":"Product 1","sku":"4242"}
Instead of:
[{"0":{"Description":"Product Description"},"1":{"Short Description":"shortdescription"},"2":{"Surname":"surname"},"3":{"Length":"6"},"4":{"Tip Configuration":"Blunt"},"5":{"Instrument Type":"Hemostatic Forceps"},"6":{"Curvature":"Curved"},"7":{"Working Surface Style":"Serrated with Longitudinal Groove"},"8":{"Handle":"Finger Rings"},"9":{"Material":"Stainless Steel"},"10":{"Disposable or Reusable":"Reusable"},"11":{"Sterile or Non-Sterile":"Non-Sterile"},"12":{"Latex or Latex-Free":"Latex-Free"},"13":{"Grade":"Premium OR-Grade"},"name":"Product 1","sku":"4242"}
Here's a technique that involves breaking the problem down into sensible parts -
const products =
{items:[{id:0,sku:"4242",name:"Product 1",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"6"},{attribute_code:"Tip Configuration","value":"Blunt"},{attribute_code:"Instrument Type","value":"Hemostatic Forceps"},{attribute_code:"Curvature","value":"Curved"},{attribute_code:"Working Surface Style","value":"Serrated with Longitudinal Groove"},{attribute_code:"Handle","value":"Finger Rings"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"5252",name:"Product 2",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"4"},{attribute_code:"Tip Configuration","value":"Square End"},{attribute_code:"Instrument Type","value":"Glass Forceps"},{attribute_code:"Curvature","value":"Angled"},{attribute_code:"Working Surface Style","value":"Smooth"},{attribute_code:"Handle","value":"Thumb"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"4243",name:"Product 3",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"6"},{attribute_code:"Tip Configuration","value":"Blunt"},{attribute_code:"Instrument Type","value":"Hemostatic Forceps"},{attribute_code:"Curvature","value":"Curved"},{attribute_code:"Working Surface Style","value":"Serrated with Longitudinal Groove"},{attribute_code:"Handle","value":"Finger Rings"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"5254",name:"Product 4",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"4"},{attribute_code:"Tip Configuration","value":"Square End"},{attribute_code:"Instrument Type","value":"Glass Forceps"},{attribute_code:"Curvature","value":"Angled"},{attribute_code:"Working Surface Style","value":"Smooth"},{attribute_code:"Handle","value":"Thumb"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]}]}
const flattenAttributes = ({ custom_attributes = [], ...product }) =>
{ const mergeAttribute = (r = {}, { attribute_code = "", value = "" }) =>
Object.assign(r, { [attribute_code]: value })
const flat =
custom_attributes.reduce(mergeAttribute, {})
return { ...product, custom_attributes: flat }
}
console.log(products.items.map(flattenAttributes))
Here's the output -
[ { id: 0,
sku: '4242',
name: 'Product 1',
attributeSetId: 0,
price: 0,
status: 0,
visibility: 0,
typeId: 'string',
createdAt: 'string',
updatedAt: 'string',
weight: 0,
extensionAttributes: [],
productLinks: [],
options: [],
mediaGalleryEntries: [],
tierPrices: [],
custom_attributes:
{ Description: 'Product Description',
'Short Description': 'shortdescription',
Surname: 'surname',
Length: '6',
'Tip Configuration': 'Blunt',
'Instrument Type': 'Hemostatic Forceps',
Curvature: 'Curved',
'Working Surface Style': 'Serrated with Longitudinal Groove',
Handle: 'Finger Rings',
Material: 'Stainless Steel',
'Disposable or Reusable': 'Reusable',
'Sterile or Non-Sterile': 'Non-Sterile',
'Latex or Latex-Free': 'Latex-Free',
Grade: 'Premium OR-Grade' } },
... ]
If you just want name and sku inline with custom_attributes, consider this slight modification -
const products =
{items:[{id:0,sku:"4242",name:"Product 1",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"6"},{attribute_code:"Tip Configuration","value":"Blunt"},{attribute_code:"Instrument Type","value":"Hemostatic Forceps"},{attribute_code:"Curvature","value":"Curved"},{attribute_code:"Working Surface Style","value":"Serrated with Longitudinal Groove"},{attribute_code:"Handle","value":"Finger Rings"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"5252",name:"Product 2",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"4"},{attribute_code:"Tip Configuration","value":"Square End"},{attribute_code:"Instrument Type","value":"Glass Forceps"},{attribute_code:"Curvature","value":"Angled"},{attribute_code:"Working Surface Style","value":"Smooth"},{attribute_code:"Handle","value":"Thumb"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"4243",name:"Product 3",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"6"},{attribute_code:"Tip Configuration","value":"Blunt"},{attribute_code:"Instrument Type","value":"Hemostatic Forceps"},{attribute_code:"Curvature","value":"Curved"},{attribute_code:"Working Surface Style","value":"Serrated with Longitudinal Groove"},{attribute_code:"Handle","value":"Finger Rings"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]},{id:0,sku:"5254",name:"Product 4",attributeSetId:0,price:0,status:0,visibility:0,typeId:"string",createdAt:"string",updatedAt:"string",weight:0,extensionAttributes:[],productLinks:[],options:[],mediaGalleryEntries:[],tierPrices:[],custom_attributes:[{attribute_code:"Description","value":"Product Description"},{attribute_code:"Short Description","value":"shortdescription"},{attribute_code:"Surname","value":"surname"},{attribute_code:"Length","value":"4"},{attribute_code:"Tip Configuration","value":"Square End"},{attribute_code:"Instrument Type","value":"Glass Forceps"},{attribute_code:"Curvature","value":"Angled"},{attribute_code:"Working Surface Style","value":"Smooth"},{attribute_code:"Handle","value":"Thumb"},{attribute_code:"Material","value":"Stainless Steel"},{attribute_code:"Disposable or Reusable","value":"Reusable"},{attribute_code:"Sterile or Non-Sterile","value":"Non-Sterile"},{attribute_code:"Latex or Latex-Free","value":"Latex-Free"},{attribute_code:"Grade","value":"Premium OR-Grade"}]}]}
const flattenAttributes = ({ name = "", sku = "", custom_attributes = [] }) =>
{ const mergeAttribute = (r = {}, { attribute_code = "", value = "" }) =>
Object.assign(r, { [attribute_code]: value })
const flat =
custom_attributes.reduce(mergeAttribute, {})
return { ...flat, name, sku }
}
console.log(products.items.map(flattenAttributes))
This matches your expected output -
[ { Description: 'Product Description',
'Short Description': 'shortdescription',
Surname: 'surname',
Length: '6',
'Tip Configuration': 'Blunt',
'Instrument Type': 'Hemostatic Forceps',
Curvature: 'Curved',
'Working Surface Style': 'Serrated with Longitudinal Groove',
Handle: 'Finger Rings',
Material: 'Stainless Steel',
'Disposable or Reusable': 'Reusable',
'Sterile or Non-Sterile': 'Non-Sterile',
'Latex or Latex-Free': 'Latex-Free',
Grade: 'Premium OR-Grade',
name: 'Product 1',
sku: '4242' },
... ]
Array.map always returns an array, since what you want is a generic object, map is not what you want.
var products = {
"items": [
{
"id": 0,
"sku": "4242",
"name": "Product 1",
"attributeSetId": 0,
"price": 0,
"status": 0,
"visibility": 0,
"typeId": "string",
"createdAt": "string",
"updatedAt": "string",
"weight": 0,
"extensionAttributes": [],
"productLinks": [],
"options": [],
"mediaGalleryEntries": [],
"tierPrices": [],
"custom_attributes": [
{
"attribute_code" : "Description",
"value" : "Product Description"
},
{
"attribute_code" : "Short Description",
"value" : "shortdescription"
},
{
"attribute_code" : "Surname",
"value" : "surname"
},
{
"attribute_code" : "Length",
"value" : "6"
},
{
"attribute_code" : "Tip Configuration",
"value" : "Blunt"
},
{
"attribute_code" : "Instrument Type",
"value" : "Hemostatic Forceps"
},
{
"attribute_code" : "Curvature",
"value" : "Curved"
},
{
"attribute_code" : "Working Surface Style",
"value" : "Serrated with Longitudinal Groove"
},
{
"attribute_code" : "Handle",
"value" : "Finger Rings"
},
{
"attribute_code" : "Material",
"value" : "Stainless Steel"
},
{
"attribute_code" : "Disposable or Reusable",
"value" : "Reusable"
},
{
"attribute_code" : "Sterile or Non-Sterile",
"value" : "Non-Sterile"
},
{
"attribute_code" : "Latex or Latex-Free",
"value" : "Latex-Free"
},
{
"attribute_code" : "Grade",
"value" : "Premium OR-Grade"
}
]
},
{
"id": 0,
"sku": "5252",
"name": "Product 2",
"attributeSetId": 0,
"price": 0,
"status": 0,
"visibility": 0,
"typeId": "string",
"createdAt": "string",
"updatedAt": "string",
"weight": 0,
"extensionAttributes": [],
"productLinks": [],
"options": [],
"mediaGalleryEntries": [],
"tierPrices": [],
"custom_attributes": [
{
"attribute_code" : "Description",
"value" : "Product Description"
},
{
"attribute_code" : "Short Description",
"value" : "shortdescription"
},
{
"attribute_code" : "Surname",
"value" : "surname"
},
{
"attribute_code" : "Length",
"value" : "4"
},
{
"attribute_code" : "Tip Configuration",
"value" : "Square End"
},
{
"attribute_code" : "Instrument Type",
"value" : "Glass Forceps"
},
{
"attribute_code" : "Curvature",
"value" : "Angled"
},
{
"attribute_code" : "Working Surface Style",
"value" : "Smooth"
},
{
"attribute_code" : "Handle",
"value" : "Thumb"
},
{
"attribute_code" : "Material",
"value" : "Stainless Steel"
},
{
"attribute_code" : "Disposable or Reusable",
"value" : "Reusable"
},
{
"attribute_code" : "Sterile or Non-Sterile",
"value" : "Non-Sterile"
},
{
"attribute_code" : "Latex or Latex-Free",
"value" : "Latex-Free"
},
{
"attribute_code" : "Grade",
"value" : "Premium OR-Grade"
}
]
},
{
"id": 0,
"sku": "4243",
"name": "Product 3",
"attributeSetId": 0,
"price": 0,
"status": 0,
"visibility": 0,
"typeId": "string",
"createdAt": "string",
"updatedAt": "string",
"weight": 0,
"extensionAttributes": [],
"productLinks": [],
"options": [],
"mediaGalleryEntries": [],
"tierPrices": [],
"custom_attributes": [
{
"attribute_code" : "Description",
"value" : "Product Description"
},
{
"attribute_code" : "Short Description",
"value" : "shortdescription"
},
{
"attribute_code" : "Surname",
"value" : "surname"
},
{
"attribute_code" : "Length",
"value" : "6"
},
{
"attribute_code" : "Tip Configuration",
"value" : "Blunt"
},
{
"attribute_code" : "Instrument Type",
"value" : "Hemostatic Forceps"
},
{
"attribute_code" : "Curvature",
"value" : "Curved"
},
{
"attribute_code" : "Working Surface Style",
"value" : "Serrated with Longitudinal Groove"
},
{
"attribute_code" : "Handle",
"value" : "Finger Rings"
},
{
"attribute_code" : "Material",
"value" : "Stainless Steel"
},
{
"attribute_code" : "Disposable or Reusable",
"value" : "Reusable"
},
{
"attribute_code" : "Sterile or Non-Sterile",
"value" : "Non-Sterile"
},
{
"attribute_code" : "Latex or Latex-Free",
"value" : "Latex-Free"
},
{
"attribute_code" : "Grade",
"value" : "Premium OR-Grade"
}
]
},
{
"id": 0,
"sku": "5254",
"name": "Product 4",
"attributeSetId": 0,
"price": 0,
"status": 0,
"visibility": 0,
"typeId": "string",
"createdAt": "string",
"updatedAt": "string",
"weight": 0,
"extensionAttributes": [],
"productLinks": [],
"options": [],
"mediaGalleryEntries": [],
"tierPrices": [],
"custom_attributes": [
{
"attribute_code" : "Description",
"value" : "Product Description"
},
{
"attribute_code" : "Short Description",
"value" : "shortdescription"
},
{
"attribute_code" : "Surname",
"value" : "surname"
},
{
"attribute_code" : "Length",
"value" : "4"
},
{
"attribute_code" : "Tip Configuration",
"value" : "Square End"
},
{
"attribute_code" : "Instrument Type",
"value" : "Glass Forceps"
},
{
"attribute_code" : "Curvature",
"value" : "Angled"
},
{
"attribute_code" : "Working Surface Style",
"value" : "Smooth"
},
{
"attribute_code" : "Handle",
"value" : "Thumb"
},
{
"attribute_code" : "Material",
"value" : "Stainless Steel"
},
{
"attribute_code" : "Disposable or Reusable",
"value" : "Reusable"
},
{
"attribute_code" : "Sterile or Non-Sterile",
"value" : "Non-Sterile"
},
{
"attribute_code" : "Latex or Latex-Free",
"value" : "Latex-Free"
},
{
"attribute_code" : "Grade",
"value" : "Premium OR-Grade"
}
]
}
]
}
var prodMap = [];
products.items.forEach( x => {
var obj = {};
x.custom_attributes.forEach( o => {
obj[o.attribute_code] = o.value;
});
prodMap.push(obj);
});
console.log(prodMap);
For those who are looking for code:
As suggested in the comments, the Object.assign() method (see MDN Docs) does the trick.
var modifiedAtt = attMap.map(item => item.reduce((acc, i)=> Object.assign({}, acc, i)))
this gives the expected output. Tested on node v10.12.0 with JavaScript.
For other readers:
Object.assign(target, sourceObj1, sourceObj2...) takes the first argument as the target and copy the values of all enumerable own properties of the other arguments (Objects) into the target Object, overwriting any that have the same key. Object.assign() returns the modified target Object.
The Array.reduce(function(sum, currentArrayValue, index, array), startValue) method (MDN) iterates over all values of an Array reducing the Array to a single value (sum). It takes a function as it's first argument, with the second, optional, argument being the starting value of the sum. The arguments for that function are an accumulator, the current value of the Array, the current index, and the Array itself. The function returns the new value of the accumulator, which is then passes to the function in the next iteration, or is the value returned from the .reduce() after the last Array value is operated upon.

TypeError: Cannot read property '0' of undefined while accessing "photo_reference" property

Below is the JSON i get from the google places API. Parsing the Json with JSON.parse(body). The "results" key is an array of Objects that i am looping through to access the property of photos. Hope the code is clearer now. I have pasted in the valid JSON that i am getting from the api call.
{
"html_attributions" : [],
"next_page_token" : "CqQCGwEAAI5PpCTJI6Qoa1CD9iA4EpJha6t0gMlZ3I3DpOIVgE1BUYh5NNI0lXRuvAltI8RhOilTNJggXsR3TEP2C6hoIsibEWZXnZClbEcZzes7LGqJuQ0heJWipe7RNbxq8S8zuao1HWfECs11i44WO0Luv-4bYx5GlCEj6Wl07LitkzwG4u0e4FyIHogyaShky5Awd44ZyOcqKzy7wYBr7p37j6A6PMdR7zn7cMWQKiVolfHQbFZerVJ3JJ5MiKSshocG189wPKjqJzSACE6W19LmZ7TIMB9qm7jQANNQStrsq7rYAWIBQ-UqJ_6Hv9jv1xL7eRQ9bkyR17u7xPZWfeCU69u_PQmGvuvSWNJDvNUuoI-uwLc_RhgTZp26kyzMlXwYHRIQXy13ridwzgvlBU8ez_y-WBoUcBN7UvN8Q8iuDyS_LjXEWmT_sIk",
"results" : [
{
"geometry" : {
"location" : {
"lat" : 28.615572,
"lng" : 77.3468
},
"viewport" : {
"northeast" : {
"lat" : 28.6169209802915,
"lng" : 77.34814898029151
},
"southwest" : {
"lat" : 28.6142230197085,
"lng" : 77.34545101970849
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
"id" : "dea8496f678dc1f01381a85298e37a0905a3ca11",
"name" : "Malabar Junction Restaurant",
"opening_hours" : {
"open_now" : true,
"weekday_text" : []
},
"photos" : [
{
"height" : 746,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/117230637789134827076/photos\"\u003eSwati\u003c/a\u003e"
],
"photo_reference" : "CmRaAAAArbpjr1fjNp2Fc4ww8Vkgrzzzt5aHEvACzEZFa-XCJU3Fw2JqFLSDo64jlFWwDZwdYaFP_cIgdqI37TJ25mVB2W_rtoTv_aI0LJGgnh_P4-UF7u45ZvqdM-bE4ljYD2yyEhDjv-4AWC5AKcE713GL1qAsGhQjAN2oS1KWv52f8XsjEK3Pmnv53w",
"width" : 750
}
],
"place_id" : "ChIJx6qqqj3lDDkRcBw22oTfWgk",
"reference" : "CmRRAAAAZBpNfAiO2G_y57bLoFTSM28MG4xUi-VAg3kJgV2ZzksdhpzySwxdPNdPP1paEIE46i70oxgLHliUcEjxalukNEyhN85J-ryRbXVVMkg4Tz-MGBGhgVur7SV5b4IFePnfEhABXu9pHswL4Up5w-k9td94GhSDs13DRQVxPOpI8iWqUbLyd_WJUg",
"scope" : "GOOGLE",
"types" : [ "restaurant", "food", "point_of_interest", "establishment" ],
"vicinity" : "62, 8, Rani Jhansi Marg, Block 10, Sector 10, Noida"
}
],
"status" : "OK"
}
Trying to Access the photo_reference property like so
let resultJSON = JSON.parse(body);
let results = resultJSON["results"];
for (var i = 0; i < results.length; i++) {
let name = results[i]["name"];
console.log(results[i].photos[0].photo_reference);
}
Here is a snippet that shows your updated code is working.
let resultJSON = {
"html_attributions": [],
"next_page_token": "CqQCGwEAAI5PpCTJI6Qoa1CD9iA4EpJha6t0gMlZ3I3DpOIVgE1BUYh5NNI0lXRuvAltI8RhOilTNJggXsR3TEP2C6hoIsibEWZXnZClbEcZzes7LGqJuQ0heJWipe7RNbxq8S8zuao1HWfECs11i44WO0Luv-4bYx5GlCEj6Wl07LitkzwG4u0e4FyIHogyaShky5Awd44ZyOcqKzy7wYBr7p37j6A6PMdR7zn7cMWQKiVolfHQbFZerVJ3JJ5MiKSshocG189wPKjqJzSACE6W19LmZ7TIMB9qm7jQANNQStrsq7rYAWIBQ-UqJ_6Hv9jv1xL7eRQ9bkyR17u7xPZWfeCU69u_PQmGvuvSWNJDvNUuoI-uwLc_RhgTZp26kyzMlXwYHRIQXy13ridwzgvlBU8ez_y-WBoUcBN7UvN8Q8iuDyS_LjXEWmT_sIk",
"results": [{
"geometry": {
"location": {
"lat": 28.615572,
"lng": 77.3468
},
"viewport": {
"northeast": {
"lat": 28.6169209802915,
"lng": 77.34814898029151
},
"southwest": {
"lat": 28.6142230197085,
"lng": 77.34545101970849
}
}
},
"icon": "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
"id": "dea8496f678dc1f01381a85298e37a0905a3ca11",
"name": "Malabar Junction Restaurant",
"opening_hours": {
"open_now": true,
"weekday_text": []
},
"photos": [{
"height": 746,
"html_attributions": [
"\u003ca href=\"https://maps.google.com/maps/contrib/117230637789134827076/photos\"\u003eSwati\u003c/a\u003e"
],
"photo_reference": "CmRaAAAArbpjr1fjNp2Fc4ww8Vkgrzzzt5aHEvACzEZFa-XCJU3Fw2JqFLSDo64jlFWwDZwdYaFP_cIgdqI37TJ25mVB2W_rtoTv_aI0LJGgnh_P4-UF7u45ZvqdM-bE4ljYD2yyEhDjv-4AWC5AKcE713GL1qAsGhQjAN2oS1KWv52f8XsjEK3Pmnv53w",
"width": 750
}],
"place_id": "ChIJx6qqqj3lDDkRcBw22oTfWgk",
"reference": "CmRRAAAAZBpNfAiO2G_y57bLoFTSM28MG4xUi-VAg3kJgV2ZzksdhpzySwxdPNdPP1paEIE46i70oxgLHliUcEjxalukNEyhN85J-ryRbXVVMkg4Tz-MGBGhgVur7SV5b4IFePnfEhABXu9pHswL4Up5w-k9td94GhSDs13DRQVxPOpI8iWqUbLyd_WJUg",
"scope": "GOOGLE",
"types": ["restaurant", "food", "point_of_interest", "establishment"],
"vicinity": "62, 8, Rani Jhansi Marg, Block 10, Sector 10, Noida"
}],
"status": "OK"
}
let results = resultJSON["results"];
for (var i = 0; i < results.length; i++) {
let name = results[i]["name"];
console.log(results[i].photos[0].photo_reference);
}

How to use if statement inside JSON?

How to use if statement inside JSON Here is the code:
.......................................................................................
var config =
[
{
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
},
{
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
},
{
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
}
],
//define if steps should change automatically
autoplay = false,
//timeout for the step
showtime,
//current step of the tour
step = 0,
//total number of steps
total_steps = config.length;
This is the required result something like this:
var config =
[
if(page==true) {
{
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
},
{
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
}
} else {
{
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
}
}
],
//define if steps should change automatically
autoplay = false,
//timeout for the step
showtime,
//current step of the tour
step = 0,
//total number of steps
total_steps = config.length;
Actually this way is wrong and makes a JavaScript syntax error.
Validating the JSON Schema Draft-07, JSON now supports the if...then...else keywords for conditional data representation.
Here is a quick example:
{
"type": "integer",
"minimum": 1,
"maximum": 1000,
"if": { "minimum": 100 },
"then": { "multipleOf": 100 },
"else": {
"if": { "minimum": 10 },
"then": { "multipleOf": 10 }
}
}
Edits
Using the OP's example in the context, it can be written like this:
{
"if": {
"page": true
},
"then": [
{
"name": "SiteTitle",
"bgcolor": "",
"color": "",
"position": "TL",
"text": "step1",
"time": 5000
},
{
"name": "Jawal",
"bgcolor": "",
"color": "",
"text": "step2",
"position": "BL",
"time": 5000
}
],
"else": [
{
"name": "Password",
"bgcolor": "",
"color": "",
"text": "step3",
"position": "TL",
"time": 5000
}
]
}
That's regular JavaScript, not JSON. Move the if statement outside:
if (page) {
var config = [
{
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
}, {
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
}
];
} else {
var config = [
{
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
}
];
}
you can add an if inside JSON.
const config = [
...(page ? [
{
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
},
{
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
}] : [{
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
}]),
];
or perhaps this:
var config =
(page == true) ?
[
{
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
},
{
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
}
:
{
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
}
];
You can do it this way also (not saying this is the best way but it's another way and could be useful in some scenarios)
let config = [];
if (page) {
config.push({
"name" : "SiteTitle",
"bgcolor" : "",
"color" : "",
"position" : "TL",
"text" : "step1",
"time" : 5000
});
config.push({
"name" : "Jawal",
"bgcolor" : "",
"color" : "",
"text" : "step2",
"position" : "BL",
"time" : 5000
});
} else {
config.push({
"name" : "Password",
"bgcolor" : "",
"color" : "",
"text" : "step3",
"position" : "TL",
"time" : 5000
});
}
You can use a library jsoncode that allows you to apply logical expressions directly into JSON and get the necessary result according to the transmitted model:
import jsoncode from './jsoncode.lib.mjs';
const json_src = {
"configs [AS ARRAY]": {
"[...IF page]": [
{
"name": "SiteTitle",
"bgcolor": "",
"color": "",
"position": "TL",
"text": "step1",
"time": 5000
}, {
"name": "Jawal",
"bgcolor": "",
"color": "",
"text": "step2",
"position": "BL",
"time": 5000
}
],
"[IF !page]": {
"name": "Password",
"bgcolor": "",
"color": "",
"text": "step3",
"position": "TL",
"time": 5000
}
}
};
const configsA = jsoncode(json_src, { page: true }).configs;
const configsB = jsoncode(json_src, { page: false }).configs;
console.log('configsA:', configsA);
console.log('configsB:', configsB);
https://www.npmjs.com/package/jsoncode

Categories