Related
I have an array that has objects, within which is an array of objects as shown below.
const property = [
{
houses: {
"id": "HT-00001",
"features": [{ "id": "FT-0001", "name": "balcony"}, { "id": "FT-0002", "name": "wifi"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
{
houses: {
"id": "HT-00002",
"features": [{ "id": "FT-0003", "name": "tiled floor"}, { "id": "FT-0002", "name": "wifi"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
{
houses: {
"id": "HT-00003",
"features": [{ "id": "FT-0004", "name": "refrigerator"}, { "id": "FT-0005", "name": "microwave"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
];
Now, I am getting a challenge extracting a unique list of features name as an array. Take note that the features has objects and it is within houses object which is an object of object of the array that I am dealing with. What I want is just an array of all unique feature names that are within the provided property array. This is what I have tried, even though it is so much confusing and I need your help.
const allFeatures = property?.map((propertyItem) => {
let features = Array.from(new Set(propertyItem?.houses?.features?.map(({ name }) => name)));
return features;
});
The expected array will be something like:
allFeatures = ['balcony', 'wifi', 'tiled floor', 'refrigerator', 'microwave']
Iterate over each "house" object and, further, iterate over each features array within each object. You can use map for that inner iteration, but to get a resulting flattened array use flatMap for the outer iteration. You can then create a set from that, and then get the depuped array from that set.
(Note: in my experience if you put your code all on one line it makes it more difficult to debug.)
const property=[{houses:{id:"HT-00001",features:[{id:"FT-0001",name:"balcony"},{id:"FT-0002",name:"wifi"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}},{houses:{id:"HT-00002",features:[{id:"FT-0003",name:"tiled floor"},{id:"FT-0002",name:"wifi"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}},{houses:{id:"HT-00003",features:[{id:"FT-0004",name:"refrigerator"},{id:"FT-0005",name:"microwave"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}}];
const allFeatures = property.flatMap(obj => {
return obj.houses.features.map(feature => {
return feature.name;
});
});
const deduped = [...new Set(allFeatures)];
console.log(deduped);
As #andy has indicated Array#flatMap, Array#map and [...new Set(features)] is the way to go. Here, I'm using arrow functions and Object destructuring as well.
const property = [ { houses: { "id": "HT-00001", "features": [{ "id": "FT-0001", "name": "balcony"}, { "id": "FT-0002", "name": "wifi"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } }, { houses: { "id": "HT-00002", "features": [{ "id": "FT-0003", "name": "tiled floor"}, { "id": "FT-0002", "name": "wifi"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } }, { houses: { "id": "HT-00003", "features": [{ "id": "FT-0004", "name": "refrigerator"}, { "id": "FT-0005", "name": "microwave"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } } ],
features = [...new Set(
property.flatMap(
({houses:{features}}) => features.map(({name}) => name)
)
)];
console.log( features );
There are two types of objects. The first one is pretty simple:
{
"status": "200",
"dump": {
"id": "213ad4c0",
"product": {
"productName": "Bicycle"
},
"components": {
"steering": {
"id": "HB2",
"description": "Handlebar",
"quantity": 1,
"spare_part": false,
"material": "steel"
},
"wheel": {
"id": "WH8",
"description": "Wheel",
"quantity": 2,
"spare_part": true,
"material": "steel"
}
}
}
}
I wanted to delete spare_part property from it and it could've been done with the following:
Object.entries(myResponse.dump.components).forEach(([key, value]) => {
delete value.spare_part;
});
Things get complicated when an object is composed of nested objects like:
{
"status": "200",
"dump": {
"id": "8e8cd4ee",
"product": {
"productName": "Car"
},
"components": {
"suspension": {
"id": "SU_02",
"description": "Suspension",
"quantity": 1,
"spare_part": false,
"material": "mixed",
"subcomponents": {
"S_FRONTAL": {
"id": "SU_02_F",
"description": "Suspension Front",
"quantity": 1,
"spare_part": false,
"material": "mixed",
"subcomponents": {
"DAMPER_L": {
"id": "SU_D_L_12",
"description": "Damper Front Left",
"quantity": 1,
"spare_part": true,
"material": "mixed"
},
"DAMPER_R": {
"id": "SU_D_R_12",
"description": "Damper Front Right",
"quantity": 1,
"spare_part": true,
"material": "mixed"
}
}
}
}
}
}
}
}
How can I gracefully walk through all levels of nesting and delete the spare_part property?
By gracefully I mean no manual key chaining in Object.entries() arguments :-)
You can use recursion, like this:
const removeSpareParts = (components) => {
Object.values(components).forEach((component) => {
delete component.spare_part;
if (component.subcomponents) {
removeSpareParts(component.subcomponents);
}
});
};
removeSpareParts(myResponse.dump.components);
This will go through each given layer-1 component, delete its spare part, and recursively do the same for all its subcomponents.
In REACT JS, I have a JSON object in state component "myrecords" where items are grouped by their Company Names and it has following format:
{
"Master Automotives": [
{
"SparePartID": "43",
"Name": "Oil and Lubricants",
"Price": "4500",
"VendorID": "48",
"CompanyName": "Master Automotives",
"Qty": 1,
"TotalPrice": "4500"
},
{
"SparePartID": "45",
"Name": "Lights",
"Price": "2300",
"VendorID": "48",
"CompanyName": "Master Automotives",
"Qty": 1,
"TotalPrice": "2300"
}
],
"Repair Solutions": [
{
"SparePartID": "47",
"Name": "Steering Wheel",
"Price": "1500",
"VendorID": "60",
"CompanyName": "Repair Solutions",
"Qty": 1,
"TotalPrice": "1500"
}
],
"FiveStar Automotives": [
{
"SparePartID": "51",
"Name": "Brakes",
"Price": "234",
"VendorID": "70",
"CompanyName": "FiveStar Automotives",
"Qty": 1,
"TotalPrice": "234"
},
{
"SparePartID": "53",
"Name": "Clutch",
"Price": "999",
"VendorID": "70",
"CompanyName": "FiveStar Automotives",
"Qty": 1,
"TotalPrice": "999"
},
{
"SparePartID": "55",
"Name": "LED",
"Price": "288",
"VendorID": "70",
"CompanyName": "FiveStar Automotives",
"Qty": 1,
"TotalPrice": "288"
}
]
}
Im using this method to remove a specific item from myrecords state whenever delete button against an item is clicked:
removeCartItem(CompanyName, sid,e)
{
const items = {...this.state.myrecords};
const j = items[CompanyName].findIndex(item => item.SparePartID === sid);
items[CompanyName].splice([j], 1);
this.setState({
myrecords: items
});
}
Im sending CompanyName, SparePartID as sid in parameters of function to perform delete.
It works Perfectly FINE and deletes the item on which I click.
But problem is if a Company has only 1 item and I delete it, then still the myreocords JSON Object contains that Company with an empty array(no items). Instead I wanted it to delete such a Company who has no Items left in it.
SO that myrecords state should have only those Companies Data whose items are present.
Please help me to solve this Problem.
You should to remove node if it have no items:
removeCartItem(CompanyName, sid,e) {
const items = {...this.state.myrecords};
const j = items[CompanyName].findIndex(item => item.SparePartID === sid);
items[CompanyName].splice([j], 1);
// rm company node if it have no items
if (items[CompanyName].length === 0) {
delete items[CompanyName]
}
this.setState({
myrecords: items
});
}
I have a universal variable on my website which includes line items with relevant details. These line items are reflective of what the user has in their cart. I am integrating with a third party who require the data passed through to them to be formatted slightly different. The below is the data layer currently on my website:
"lineItems": [
{
"product": {
"id": "s83y016b5",
"sku_code": "s83y016b5",
"url": "/en-gb/jeans/p/s83y016b5",
"image_url": "http://www.my-website.com/a/p/shirt.jpeg",
"name": "Jeans",
"manufacturer": "",
"category": "Everyday Wear",
"stock": 116,
"currency": "GBP",
"unit_sale_price": 16,
"unit_price": 16,
"size": "6-9 Months",
"color": "Indigo"
},
"quantity": 1
}
]
The below is what format the third party needs:
"lineItems": [
{
"sku": "s83y016b5",
"name": "Jeans",
"description": "A super great pair of jeans.",
"category": "Everyday Wear",
"other": {"fieldName": "This can be a string or any value you like"}
"unitPrice": 11.99,
"salePrice": 11.99,
"quantity": 2,
"totalPrice": 23.98
"imageUrl": "http://www.my-website.com/a/p/shirt.jpeg",
"productUrl": "http://www.my-website.com/index.php/shirt.html",
}]
Obviously this needs to be dynamic based on the products in the cart. What I intend to do is use javascript to amend the data and send this to the third party via Google Tag Manager.
Any help would be greatly appreciated. Any questions welcome.
This should be close to what you're looking for.
let oldLineItems = "your object";
let newLineItems = {};
newLineItems.lineItems = [];
for (let i in oldLineItems.lineItems) {
newLineItems.lineItems[i] = {};
for (let key in oldLineItems.lineItems[i].product)
{
newLineItems.lineItems[i][key] = oldLineItems.lineItems[i].product[key];
}
}
See code below.
I'm not sure how your lineItems object is set up, but below I just created an array called line Items. If line items is a key in an object which I suspect from your snippet above, you will have to go a level deeper in the for loops used in my example below.
Simply add further details to the new object in the nested for in loops below.
var lineItems =
[
{
"product": {
"id": "s83y016b5",
"sku_code": "s83y016b5",
"url": "/en-gb/jeans/p/s83y016b5",
"image_url": "http://www.my-website.com/a/p/shirt.jpeg",
"name": "Jeans",
"manufacturer": "",
"category": "Everyday Wear",
"stock": 116,
"currency": "GBP",
"unit_sale_price": 16,
"unit_price": 16,
"size": "6-9 Months",
"color": "Indigo",
"description": 'Some random description'
},
"quantity": 1
},
{
"product": {
"id": "s83y01699",
"sku_code": "s83y01699",
"url": "/en-gb/pants/p/s83y016b5",
"image_url": "http://www.my-website.com/a/p/pants.jpeg",
"name": "Pants",
"manufacturer": "",
"category": "Casual Wear",
"stock": 90,
"currency": "au",
"unit_sale_price": 14,
"unit_price": 14,
"size": "6-9 Months",
"color": "Indigo",
"description": 'Some random description'
},
"quantity": 14
},
];
var newLineItems = [];
for(var char in lineItems){
// Adding some values to newLineItems.
newLineItems.push({
sku: lineItems[char].product.sku_code,
name: lineItems[char].product.name,
description: lineItems[char].product.description,
category: lineItems[char].product.category,
quantity: lineItems[char].quantity
});
}
console.log(JSON.stringify(newLineItems));
i want to create a form which can submit the values as the below format
[
{
"_id": "59817f39808768495728ae94",
"updatedAt": "2017-08-02T07:33:00.578Z",
"createdAt": "2017-08-02T07:28:57.310Z",
"farmId": "tesform",
"farmName": "tesform",
"gatewayId": "123",
"gatewayName": "testform getway",
"userId": "abc#kisanraja.com",
"description": "test details 1st time",
"nodes": [
{
"permanentAddress": "",
"description": "with temparature",
"name": "Node 1",
"_id": "5981802c808768495728ae9b",
"sensors": [
{
"units": "C",
"max": 60,
"min": -6,
"name": "temparature",
"_id": "5981802c808768495728ae9c"
}
],
"shortAddress": 0
},
{
"permanentAddress": "",
"description": "with soil moisture and voltage",
"name": "Node 2",
"_id": "5981802c808768495728ae98",
"sensors": [
{
"units": "C",
"max": 60,
"min": -6,
"name": "moisture",
"_id": "5981802c808768495728ae9a"
},
{
"units": "C",
"max": 60,
"min": -6,
"name": "voltage",
"_id": "5981802c808768495728ae99"
}
],
"shortAddress": 0
}
]
}
]
I want to create the nodes and sensors dynamically using jquery. Each farm should have more than one node, and each node may have more than one sensor.
You can add different class names to different level inputs, then each them, when came cross nodes, add nodes to object, when came cross to sensors, then add sensors to array as an attributes of node object named sensors when submit the form:
$("#form").submit(function() {
//deal with them;
});