Change JSON format/layout - javascript

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));

Related

How to get an array of object values embedded within an array of objects

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 );

How can I .filter an object by elements within an array inside an object?

I've been playing around trying to learn in an API project using Postman and conducting tests using JavaScript. So far, I have succeeded with the help of reading on websites and watching YouTube videos. Of course, previous tests and playing around have been fairly easy but now I came to a stop. I really tried to figure this out for several weeks but I need further guidance, a push in the right direction or direct help.
What I'm trying to do is to filter out some of the response to only view objects that contain specific data.
To do that, I'm using a filter where I want all products containing a specific value inside an array "product_option_values".
My first approach was to see if I could sort products having any values from the first array, and it worked. It filters just fine.
var filterSmall = jsonData.products.filter(fs => fs.associations.product_option_values);
My next approach was to get to my goal of filtering out products according to specific values inside this array. I tried many simple .(dot) combinations and pointing to [index] to access it without any luck. (I must add that I know how to access this from a specific product, but that way doesn't work when filtering).
I've also tried other approaches such as:
var filterSmall = jsonData.products.filter(fs => fs.associations["product_option_values", 0, "name"] === "S");
and other similar combinations.
This is a very shortened sample of the structure of "products" which in its full form consists of 20 products and far more values inside of it:
{
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
}
and here is a small and expanded sample from product_option_values:
{
"product_option_values": [
{
"id": 1,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
}
How do I proceed? Did I do anything correct or even close to it?
Perhaps I've been staring at this for too long.
Thanks in advance.
If you want to compare nested attributes you have to transform the objects (e.g. by using a map operation), so that the relevant attributes are easily accessible for a comparison. If you want to filter by product_option_value id, you could do something like this:
const jsonData = {
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
};
const sample = {
"product_option_values": [
{
"id": 22,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
};
const ids = sample.product_option_values.map((el) => String(el.id));
console.log(ids);
const filtered = jsonData.products.filter((fs) => fs.associations.product_option_values.map((e) => e.id).some((f) => ids.includes(f)));
console.log(filtered);

What methods do I use to manipulate data of an array within an Object? (Pseudo Code only)

Backstory (skipable):
Hello, I'm a student at Lambda school. Recently we had a JS assessment test in order to progress to the next unit, but I wounded up flunking it twice. So now I have to repeat Unit 1. I'm here today in order to finally knock out that damn exam. I don't have a problem working with Arrays or Objects, what I do have a problem with is figuring out a way to solve issues when they are combined. It's like: "What the hell, do I use map or Object.Key?" Those types of problems appeared throughout the exam. It's fine to challenge students, but I never worked with both at the same time before. The approach was completely lost on me and before I knew it, my 3 hours were up two days straight.
What I hope you can provide:
I'm going to provide one problem and show you the work that I did. What I would like is for you to formulate pseudo code for me to work out that problem. I need to learn how to use Pseudo code if I want to be a good web engineer. Please do not solve the problem for me, all I ask is pseudo code. I'll try to work on the problem based on the pseudo code I feel is manageable for me to do. Thanks in Advance.
Problem and current Status:
/**
* ### Challenge `getSecondStarshipName`
* MVP Challenge 🤓
*
* #instructions
* Return second starship's name from `starships` property.
* If length is 0. Return 'none'
*/
function getSecondStarshipName(character) {
// TODO: Add your code here.
const checkProperty = character.hasOwnProperty("starships");
const checkArray = character.isArray("starships");
const secondShipLength = character.starships[1].length;
const secondShipName = character.starships[1].name;
if (checkProperty && checkArray) {
if (secondShipLength >= 2) {
return secondShipName;
} else {
return "none";
}
} else {
return "none";
}
}
Data
window.lukeSkywalker = require('./person-1.json')
window.leiaOrgana = require('./person-5.json')
window.obiWanKenobi = require('./person-10.json')
},{"./person-1.json":2,"./person-10.json":3,"./person-5.json":4}],2:[function(require,module,exports){
module.exports={
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"homeworld": "Tatooine",
"films": [
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"Revenge of the Sith",
"The Force Awakens"
],
"species": [
"Human"
],
"vehicles": [
{
"name": "Snowspeeder",
"model": "t-47 airspeeder",
"manufacturer": "Incom corporation",
"cost_in_credits": null,
"length": "4.5",
"max_atmosphering_speed": "650",
"crew": 2,
"passengers": 0,
"cargo_capacity": "10"
},
{
"name": "Imperial Speeder Bike",
"model": "74-Z speeder bike",
"manufacturer": "Aratech Repulsor Company",
"cost_in_credits": 8000,
"length": "3",
"max_atmosphering_speed": "360",
"crew": 1,
"passengers": 1,
"cargo_capacity": "4"
}
],
"starships": [
{
"name": "X-wing",
"model": "T-65 X-wing",
"manufacturer": "Incom Corporation",
"cost_in_credits": 149999,
"length": "12.5",
"max_atmosphering_speed": "1050",
"crew": 1,
"passengers": 0,
"cargo_capacity": "110",
"consumables": "1 week",
"hyperdrive_rating": "1.0",
"MGLT": "100",
"starship_class": "Starfighter"
},
{
"name": "Imperial shuttle",
"model": "Lambda-class T-4a shuttle",
"manufacturer": "Sienar Fleet Systems",
"cost_in_credits": 240000,
"length": "20",
"max_atmosphering_speed": "850",
"crew": 6,
"passengers": 20,
"cargo_capacity": "80000",
"consumables": "2 months",
"hyperdrive_rating": "1.0",
"MGLT": "50",
"starship_class": "Armed government transport"
}
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
}
},{}],3:[function(require,module,exports){
module.exports={
"name": "Obi-Wan Kenobi",
"height": "182",
"mass": "77",
"hair_color": "auburn, white",
"skin_color": "fair",
"eye_color": "blue-gray",
"birth_year": "57BBY",
"gender": "male",
"homeworld": "Stewjon",
"films": [
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"The Phantom Menace",
"Attack of the Clones",
"Revenge of the Sith"
],
"species": [
"Human"
],
"vehicles": [
{
"name": "Tribubble bongo",
"model": "Tribubble bongo",
"manufacturer": "Otoh Gunga Bongameken Cooperative",
"cost_in_credits": null,
"length": "15",
"max_atmosphering_speed": "85",
"crew": 1,
"passengers": 2,
"cargo_capacity": "1600"
}
],
"starships": [
{
"name": "Jedi starfighter",
"model": "Delta-7 Aethersprite-class interceptor",
"manufacturer": "Kuat Systems Engineering",
"cost_in_credits": 180000,
"length": "8",
"max_atmosphering_speed": "1150",
"crew": 1,
"passengers": 0,
"cargo_capacity": "60",
"consumables": "7 days"
},
{
"name": "Trade Federation cruiser",
"model": "Providence-class carrier/destroyer",
"manufacturer": "Rendili StarDrive, Free Dac Volunteers Engineering corps.",
"cost_in_credits": 125000000,
"length": "1088",
"max_atmosphering_speed": "1050",
"crew": 600,
"passengers": 48247,
"cargo_capacity": "50000000",
"consumables": "4 years"
},
{
"name": "Naboo star skiff",
"model": "J-type star skiff",
"manufacturer": "Theed Palace Space Vessel Engineering Corps/Nubia Star Drives, Incorporated",
"cost_in_credits": null,
"length": "29.2",
"max_atmosphering_speed": "1050",
"crew": 3,
"passengers": 3,
"cargo_capacity": null,
"consumables": null
},
{
"name": "Jedi Interceptor",
"model": "Eta-2 Actis-class light interceptor",
"manufacturer": "Kuat Systems Engineering",
"cost_in_credits": 320000,
"length": "5.47",
"max_atmosphering_speed": "1500",
"crew": 1,
"passengers": 0,
"cargo_capacity": "60",
"consumables": "2 days"
},
{
"name": "Belbullab-22 starfighter",
"model": "Belbullab-22 starfighter",
"manufacturer": "Feethan Ottraw Scalable Assemblies",
"cost_in_credits": 168000,
"length": "6.71",
"max_atmosphering_speed": "1100",
"crew": 1,
"passengers": 0,
"cargo_capacity": "140",
"consumables": "7 days"
}
],
"created": "2014-12-10T16:16:29.192000Z",
"edited": "2014-12-20T21:17:50.325000Z",
"url": "https://swapi.co/api/people/10/"
}
},{}],4:[function(require,module,exports){
module.exports={
"name": "Leia Organa",
"height": "150",
"mass": "49",
"hair_color": "brown",
"skin_color": "light",
"eye_color": "brown",
"birth_year": "19BBY",
"gender": "female",
"homeworld": "Alderaan",
"films": [
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"Revenge of the Sith",
"The Force Awakens"
],
"species": [
"Human"
],
"vehicles": [
{
"name": "Imperial Speeder Bike",
"model": "74-Z speeder bike",
"manufacturer": "Aratech Repulsor Company",
"cost_in_credits": 8000,
"length": "3",
"max_atmosphering_speed": "360",
"crew": 1,
"passengers": 1,
"cargo_capacity": "4"
}
],
"starships": [],
"created": "2014-12-10T15:20:09.791000Z",
"edited": "2014-12-20T21:17:50.315000Z",
"url": "https://swapi.co/api/people/5/"
}
},{}]},{},[1]);
How I would approach the problem (Pseudo Code):
//Create a variable called starship2nd
//Assign starship2nd the 2nd starship of each character.
//Check the length of the 2nd starship of each character. [[I'm stuck on this phase.]]
//Return 'none' after the checker function iterates through the Object's array. [[[Not sure how to do this part either..]]
Failed Solutions (Are they repairable? O_O)
solution 1 (failed)
const starship2nd = character.starships[1].name
const shipLength = starship2nd.length
function checkLength () {
if (shipLength === 0) {
return 'none'
}
return checkLength()
Thank you for your time. ^_^
Here is some pseudo code for you
if (character has property 'starships' and it is an array) {
if (length of starships is at least 2) {
return name property of second starship
} else {
return none
}
} else {
return none
}
You might think that some of those checks are overkill and not necessary since you know your input, but it is always good practice to double check properties and lengths before you begin accessing and assuming.
I hope that helps you with reasoning about the problem.

How to remove specific item from JSON object correctly in REACT js?

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

how to find a particular entry from json store using id/name

how to find a particular entry from json store using id/name? using javascript function
for eg:
var products=[{
"productId": 101,
"productName": "Nilkamal Shoe Rack",
"productPrice": 2223,
"productOriginalPrice": 2470,
"productDiscount": "20 %",
"productColor": "Sandy Brown",
"productSpecifications": [{
"Brand": "Nilakamal",
"Type": "Shoe Rack",
"Material": "Polypropylene"
}],
"productServices": ["Installation and Demo not Required", "10 Days Replacement"]
},
{
"productId": 102,
"productName": "Seagate Backup Plus Slim 1TB wired external hard disk",
"productPrice": 3899,
"productOriginalPrice": 7450,
"productDiscount": "47 %",
"productColor": "White",
"productSpecifications": [{
"Brand": "Seagate",
"Type": "External Hard Disk",
"Capacity": "1 TB",
"Connectivity": "USB 3.0",
"Ports": "1 Port"
}],
"productServices": ["3 years warranty", "10 Days Replacement"]
}]
How can I find all the details of one of the following product using id/name?
you can simply use array.find like this
var myObj = products.find(obj => obj.productId == 102);
console.log(myObj);
if you want function then
function getObjbyId(id){
var myObj = products.find(obj => obj.productId == id);
return myObj;
}

Categories

Resources