Grab multiple properties of a JSON - javascript

I'm working with a large JSON file that looks like this:
{
"name": "Superproduct",
"description": "Enjoy this amazing product.",
"brand": "ACME",
"categories": [
"Ball",
"Soccer Ball",
"Beach Ball"
],
"type": "Online product",
"price": 50,
"price_range": "50 - 100",
"image": "someImageURL",
"url": "SomeProductURL",
"free_shipping": true,
"popularity": 10000,
"rating": 2,
"objectID": "1234"
}
I am trying to access every object with the Ball category, so that I can add a discount to that specific item. I realized that every object can have multiple variations of the word Ball in the category array.
Is there a way I can target the word ball in the array, so that I can add that to an array and apply the discount to every product with said criteria?
This is what I have so far, but I'm not sure if this is the best way, or if there's a better way to accomplish what I'm trying to do:
async function setDiscount() {
let discountedRate = 0.5;
fetch('products.json')
.then(res => res.json())
.then(data => {for (let i = 0; i < data.length; i++) {
if (data[i].categories[i] == "Ball") {
data[i].price -= (data[i].price * discountedRate);
}
}});
}
setDiscount();
P.S.: I'm a newbie.

You can simply achieve this by iterating the response array.
Working Demo :
const data = [{
"name": "Superproduct",
"description": "Enjoy this amazing product.",
"brand": "ACME",
"categories": [
"Ball",
"Soccer Ball",
"Beach Ball"
],
"type": "Online product",
"price": 50,
"price_range": "50 - 100",
"image": "someImageURL",
"url": "SomeProductURL",
"free_shipping": true,
"popularity": 10000,
"rating": 2,
"objectID": "1234"
}];
const discountedRate = 0.5;
data.forEach((obj) => {
obj.price = obj.categories.includes('Ball') ? (obj.price * discountedRate) : obj.price
});
console.log(data);

Related

How to transform two Objects into one overview in Javascript?

I am currently struggling with the formatting of a map operation on two object arrays in Javascript.
So lets say we have two arrays:
var customer = [
{ "Name": "Thomas", "Address": "example street 34", "customerID": 1 },
{ "Name": "Alica", "Address": "example street 24", "customerID": 2 },
{ "Name": "John", "Address": "example bouelvard 4", "customerID": 3 }
]
var orders = [
{ "Product": "iPhone 12", "Amount": 2, "customerID": 1 },
{ "Product": "charger", "Amount": 1, "customerID": 1 },
{ "Product": "screen protection", "Amount": 5, "customerID": 2 }
]
I want to have a result array so that when I print it out, I have an overview over customers with their orders in this way:
{
customer: {
"Name": "Thomas",
"Address": "example street 34",
"customerID": 1,
},
order: [
{
"Product": "iPhone 12",
"Amount": 2,
"customerID": 1
},
{
"Product": "charger",
"Amount": 1,
"customerID": 1
}
]
}
So I basically did a map function and searched for orders with the same customer id.
let overview = customers.map(element1 => ({ ...element1, : [...(orders.filter(element => element.customerID === element1.customerID))] }));
This is what I get:
{
"Name": "Thomas",
"Address": "example street 34",
"customerID": 1,
"order": [[Object], [Object]]
}
How do I get the "customer:" before the output of the customer objects and why do I get the Object output in my order array?
try with that:
customer.map(element1 => (
{...element1, order: orders.filter(element => element.customerID === element1.customerID)}
)))
You were missing 'order' key and also don't need to spread since filter returns an array (empty if nothing filtered)
You're almost there:
let overview = customer.map(customer => ({
customer,
order: orders.filter(order => customer.customerID === order.customerID)
}))
You are so close! So very close. You can rename customer to customers just to avoid confusion the element1 becomes customer and the rest is as shown below:
const
customers = [ { "Name": "Thomas", "Address": "example street 34", "customerID": 1 }, { "Name": "Alica", "Address": "example street 24", "customerID": 2 }, { "Name": "John", "Address": "example bouelvard 4", "customerID": 3 } ],
orders = [ { "Product": "iPhone 12", "Amount": 2, "customerID": 1 }, { "Product": "charger", "Amount": 1, "customerID": 1 }, { "Product": "screen protection", "Amount": 5, "customerID": 2 } ],
custOrders = customers
.map(
customer =>
({
customer,
orders:orders
.filter(order => order.customerID === customer.customerID)
})
);
console.log( custOrders );
First you can create map from orders array where customerId will be key and array with all orders belonging to one customer will be map value.
Next is initialising empty results array and iterating customers array. While iterating, push new object to results array. New object should contain 2 fields, customer and order. customer is object from iteration and order is map value which you get from previously generate map using customer.customerID as map key.
This way, performance are increased because fetching data from Map data structure has O(1) time complexity. Using filter method to find all orders for specific customer is time consuming with complexity O(n).
const customers = [{"Name": "Thomas", "Address": "example street 34", "customerID": 1},{"Name": "Alica", "Address": "example street 24", "customerID": 2}, {"Name": "John", "Address": "example boulevard 4", "customerID": 3}];
const orders = [{"Product": "iPhone 12", "Amount": 2, "customerID": 1},{"Product": "charger", "Amount": 1, "customerID": 1},{"Product": "screen protection", "Amount": 5, "customerID": 2}];
const ordersMap = new Map();
for (const order of orders) {
const { customerID } = order;
const mapValue = ordersMap.get(customerID);
if (mapValue) {
mapValue.push(order);
} else {
ordersMap.set(customerID, [order]);
}
}
const results = [];
for (const customer of customers) {
results.push({
customer,
order: ordersMap.get(customer.customerID),
});
}
console.log(results)

accessing a json child object not in an array

I'm trying to accessing a json child object which is not in an array. i've tried accessing it with my below script but its not working. i want to be able to access the menuCategory Object
JSON
[
{
"id": 67,
"name": "Wednesday Menu",
"serveDate": "2019-06-12 00:00:00",
"expiryDate": "2019-06-12 16:11:00",
"status": "APPROVED",
"isEnabled": true,
"meals": [
{
"id": 45,
"name": "Waakye, Gari and Wele",
"description": "A very well designed food for all kids",
"image": "",
"mealType": "LUNCH",
"unitPrice": 30,
"status": "ENABLED"
},
{
"id": 46,
"name": "Gari and Beans",
"description": "A very well designed food for all kidsss",
"image": "",
"mealType": "LUNCH",
"unitPrice": 12,
"status": "ENABLED"
}
],
"menuCategory": {
"id": 2,
"name": "hello"
}
}
]
JAVASCRIPT
callEditMenu(parent, content) {
this.modalService.open(content);
this.editMenuCategoryId = parent.menuCategory.id;
}
May be like
const parent = [{"id":67,"name":"Wednesday Menu","serveDate":"2019-06-12 00:00:00","expiryDate":"2019-06-12 16:11:00","status":"APPROVED","isEnabled":true,"meals":[{"id":45,"name":"Waakye, Gari and Wele","description":"A very well designed food for all kids","image":"","mealType":"LUNCH","unitPrice":30,"status":"ENABLED"},{"id":46,"name":"Gari and Beans","description":"A very well designed food for all kidsss","image":"","mealType":"LUNCH","unitPrice":12,"status":"ENABLED"}],"menuCategory":{"id":2,"name":"hello"}}]
console.log(parent[0].menuCategory.id);
If the parent argument in the callEditMenu function is referring to the JSON you included then try parent[0].menuCategory.id
let arr = [{"id":67,"name":"Wednesday Menu","serveDate":"2019-06-12 00:00:00","expiryDate":"2019-06-12 16:11:00","status":"APPROVED","isEnabled":true,"meals":[{"id":45,"name":"Waakye, Gari and Wele","description":"A very well designed food for all kids","image":"","mealType":"LUNCH","unitPrice":30,"status":"ENABLED"},{"id":46,"name":"Gari and Beans","description":"A very well designed food for all kidsss","image":"","mealType":"LUNCH","unitPrice":12,"status":"ENABLED"}],"menuCategory":{"id":2,"name":"hello"}}]
for (let item of arr) {
if (item.hasOwnProperty("menuCategory")) {
console.log(item["menuCategory"]);
}
};
let res = arr.filter((item) => item && item.menuCategory);
console.log(res[0].menuCategory);
In case you need to find it dynamically. Above are two different ways
Considering there would be multiple items in your array of objects, you can iterate through each object to get the menuCategory name as
let obj = [
{
"id": 67,
"name": "Wednesday Menu",
"serveDate": "2019-06-12 00:00:00",
"expiryDate": "2019-06-12 16:11:00",
"status": "APPROVED",
"isEnabled": true,
"meals": [
{
"id": 45,
"name": "Waakye, Gari and Wele",
"description": "A very well designed food for all kids",
"image": "",
"mealType": "LUNCH",
"unitPrice": 30,
"status": "ENABLED"
},
{
"id": 46,
"name": "Gari and Beans",
"description": "A very well designed food for all kidsss",
"image": "",
"mealType": "LUNCH",
"unitPrice": 12,
"status": "ENABLED"
}
],
"menuCategory": {
"id": 2,
"name": "hello"
}
}
];
obj.forEach(elem => {
console.log(elem.menuCategory.name);
});

how to remove this object from array inside of object in array?

I am not sure how to form this question, but I will do my best.
I don't know how to remove object by _id from 'list:' part.
So, I have one array, and inside of that array I have list of objects,inside of these objects I have again array with objects, so I want to remove one object from that last array, how I can do that?
Cannot fix it for 2 days, I'm stucked!
Thanks!
[
{
"_id": "599a1344bf50847b0972a465",
"title": "British Virgin Islands BC",
"list": [],
"price": "1350"
},
{
"_id": "599a1322bf50847b0972a38e",
"title": "USA (Nevada) LLC",
"list": [
{
"_id": "599a1322bf50847b0972a384",
"title": "Nominee Member",
"service": "nominee-service",
"price": "300"
},
{
"_id": "599a1322bf50847b0972a385",
"title": "Nominee Manager & General Power of Attorney (Apostilled)",
"service": "nominee-service",
"price": "650"
},
{
"_id": "599a1322bf50847b0972a386",
"title": "Special Power of Attorney",
"service": "nominee-service",
"price": "290"
}
],
"price": "789"
},
{
"_id": "599a12fdbf50847b0972a2ad",
"title": "Cyprus LTD",
"list": [
{
"_id": "599a12fdbf50847b0972a2a5",
"title": "Nominee Shareholder",
"service": "nominee-service",
"price": "370"
},
{
"_id": "599a12fdbf50847b0972a2a6",
"title": "Nominee Director & General Power or Attorney (Apostilled)",
"service": "nominee-service",
"price": "720"
},
{
"_id": "599a12fdbf50847b0972a2ab",
"title": "Extra Rubber Stamp",
"service": "other-service",
"price": "40"
}
],
"price": "1290"
}
]
Using Vanilla JS:
function findAndRemove(data, id) {
data.forEach(function(obj) { // Loop through each object in outer array
obj.list = obj.list.filter(function(o) { // Filter out the object with unwanted id, in inner array
return o._id != id;
});
});
}
var data = [{
"_id": "599a1344bf50847b0972a465",
"title": "British Virgin Islands BC",
"list": [],
"price": "1350"
},
{
"_id": "599a1322bf50847b0972a38e",
"title": "USA (Nevada) LLC",
"list": [{
"_id": "599a1322bf50847b0972a384",
"title": "Nominee Member",
"service": "nominee-service",
"price": "300"
},
{
"_id": "599a1322bf50847b0972a385",
"title": "Nominee Manager & General Power of Attorney (Apostilled)",
"service": "nominee-service",
"price": "650"
},
{
"_id": "599a1322bf50847b0972a386",
"title": "Special Power of Attorney",
"service": "nominee-service",
"price": "290"
}
],
"price": "789"
},
{
"_id": "599a12fdbf50847b0972a2ad",
"title": "Cyprus LTD",
"list": [{
"_id": "599a12fdbf50847b0972a2a5",
"title": "Nominee Shareholder",
"service": "nominee-service",
"price": "370"
},
{
"_id": "599a12fdbf50847b0972a2a6",
"title": "Nominee Director & General Power or Attorney (Apostilled)",
"service": "nominee-service",
"price": "720"
},
{
"_id": "599a12fdbf50847b0972a2ab",
"title": "Extra Rubber Stamp",
"service": "other-service",
"price": "40"
}
],
"price": "1290"
}
];
// Empty almost all of list, except middle one
findAndRemove(data, "599a1322bf50847b0972a384");
findAndRemove(data, "599a1322bf50847b0972a386");
findAndRemove(data, "599a12fdbf50847b0972a2a5");
findAndRemove(data, "599a12fdbf50847b0972a2a6");
findAndRemove(data, "599a12fdbf50847b0972a2ab");
console.log(data);
Cleared everything except middle list, just for better visualization.
#Abhijit Kar your one is working perfectly, thanks mate!
How I can later splice this list?
When I was working with objects from first array, I did it like this :
var inventory = jsonArrayList;
for (var i = 0; i < inventory.length; i++) {
if (inventory[i]._id == deleteProductById) {
vm.items.splice(i, 1);
break;
}
}
It would be very helpful, thanks alot!
You can use Array.map and Array.filter to accomplish this. Detailed explanation in comments:
PS: This snippet uses ES6 arrow functions and spread operator
function removeById(arr, id) {
// Array.map iterates over each item in the array,
// and executes the given function on the item.
// It returns an array of all the items returned by the function.
return arr.map(obj => {
// Return the same object, if the list is empty / null / undefined
if (!obj.list || !obj.list.length) return obj;
// Get a new list, skipping the item with the spedified id
const newList = obj.list.filter(val => val._id !== id);
// map function returns the new object with the filtered list
return { ...obj, list: newList };
});
}
const oldArray = <YOUR_ORIGINAL_ARRAY>;
const newArray = removeById(arr, "599a12fdbf50847b0972a2a5");

Is there any way to convert a big object into smaller one in JavaScript?

Let's say i get from the server the object A
`A = {
"kind": "books#volume",
"id": "8Q1wW6Us-O0C",
"etag": "k2MS/7WPcsY",
"selfLink": "https://www.googleapis.com/books/v1/volumes/8Q1wW6Us-O0C",
"volumeInfo": {
"title": "Years with Frank Lloyd Wright",
"subtitle": "Apprentice to Genius",
"authors": [
"Edgar Tafel"
],
"publisher": "Courier Corporation",
"publishedDate": "1979",
"description": "This insightful memoir by a former apprentice presents a revealing portrait of the great American architect, providing illuminating anecdotes about Wright's Prairie home and Oak Park periods, and much more.",
"industryIdentifiers": [
{
"type": "ISBN_10",
"identifier": "0486248011"
},
{
"type": "ISBN_13",
"identifier": "9780486248011"
}
],
"readingModes": {
"text": false,
"image": true
},
"pageCount": 228,
"printType": "BOOK",
"categories": [
"Architecture"
],
"averageRating": 3.5,
"ratingsCount": 2,
"maturityRating": "NOT_MATURE",
"allowAnonLogging": false,
"contentVersion": "1.1.1.0.preview.1",
"imageLinks": {
"smallThumbnail": "http://books.google.ru/books/content?id=8Q1wW6Us-O0C&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.ru/books/content?id=8Q1wW6Us-O0C&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
"previewLink": "http://books.google.ru/books?id=8Q1wW6Us-O0C&printsec=frontcover&hl=&source=gbs_api",
"infoLink": "http://books.google.ru/books?id=8Q1wW6Us-O0C&hl=&source=gbs_api",
"canonicalVolumeLink": "http://books.google.ru/books/about/Years_with_Frank_Lloyd_Wright.html?hl=&id=8Q1wW6Us-O0C"
},
}
Is there any fast way in JavaScript to create another object from this one based on selected properties?
B = {"id": "8Q1wW6Us-O0C",
"title": "Years with Frank Lloyd Wright",
"publishedDate": "1979",
"pageCount": 228,
and some other properties}
Don't read this: I am asked to add some details, but I guess this is enough.
try this
var selectedProperties = ["id", "title", "publishedDate", "pageCount"];
var B = {};
selectedProperties.forEach( function(key){
A[key] && (B[key] = A[key]);
});
I suggest to store the path of the wanted properties
wanted = {
id: 'id',
title: 'volumeInfo.title',
publishedDate: 'volumeInfo.publishedDate',
pageCount: 'volumeInfo.pageCount'
}
and use it with Array#reduce for the value.
var data = { "kind": "books#volume", "id": "8Q1wW6Us-O0C", "etag": "k2MS/7WPcsY", "selfLink": "https://www.googleapis.com/books/v1/volumes/8Q1wW6Us-O0C", "volumeInfo": { "title": "Years with Frank Lloyd Wright", "subtitle": "Apprentice to Genius", "authors": ["Edgar Tafel"], "publisher": "Courier Corporation", "publishedDate": "1979", "description": "This insightful memoir by a former apprentice presents a revealing portrait of the great American architect, providing illuminating anecdotes about Wright's Prairie home and Oak Park periods, and much more.", "industryIdentifiers": [{ "type": "ISBN_10", "identifier": "0486248011" }, { "type": "ISBN_13", "identifier": "9780486248011" }], "readingModes": { "text": false, "image": true }, "pageCount": 228, "printType": "BOOK", "categories": ["Architecture"], "averageRating": 3.5, "ratingsCount": 2, "maturityRating": "NOT_MATURE", "allowAnonLogging": false, "contentVersion": "1.1.1.0.preview.1", "imageLinks": { "smallThumbnail": "http://books.google.ru/books/content?id=8Q1wW6Us-O0C&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api", "thumbnail": "http://books.google.ru/books/content?id=8Q1wW6Us-O0C&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api" }, "previewLink": "http://books.google.ru/books?id=8Q1wW6Us-O0C&printsec=frontcover&hl=&source=gbs_api", "infoLink": "http://books.google.ru/books?id=8Q1wW6Us-O0C&hl=&source=gbs_api", "canonicalVolumeLink": "http://books.google.ru/books/about/Years_with_Frank_Lloyd_Wright.html?hl=&id=8Q1wW6Us-O0C" } },
wanted = { id: 'id', title: 'volumeInfo.title', publishedDate: 'volumeInfo.publishedDate', pageCount: 'volumeInfo.pageCount' },
result = {};
Object.keys(wanted).forEach(function (k) {
result[k] = wanted[k].split('.').reduce(function (r, a) {
return r && r[a];
}, data);
})
console.log(result);
I am using ES6 hook advantages for this (as in react)
const {name, surname, emailid} = bigObj;
const smallObj = {name, surname, emailid};
// you can still use variables from hook seperatly
console.log(name, surname)

Sorting an array of JavaScript objects by sub array property/value

I have the following data being returned from a server (the structure of this data is something that I do not have control over)...
var data = {
"TrackingResults": [
{
"Name": "Pack One",
"Products": {
"Product": [
{
"ProductName": "Soccer Ball"
},
{
"ProductName": "Tennis Racket"
},
{
"ProductName": "Gold Putter"
}
]
},
"status": "Despatched",
"Location": "Alabama",
"Type": "Parcel"
},
{
"Name": "Pack Two",
"Products": {
"Product": [
{
"ProductName": "Backet Ball Hoop"
},
{
"ProductName": "Base Ball Glove"
}
]
},
"status": "Despatched",
"Location": "Florida",
"Type": "Parcel"
}
]
};
I would like to be able to sort each Tracking Result by the first Product Name. I can't find any code that will sort by a sub array property/value.
You should use the Array.sort method with a custom comparator function:
var resultsComparator = function (res1, res2) {
var prod1 = res1.Products.Product[0].ProductName;
var prod2 = res2.Products.Product[0].ProductName;
return prod1.localeCompare(prod2);
}
This way the ordering is based on the current locale of the web browser. You just pass the function to the sort method:
data.TrackingResults.sort(resultsComparator);
You need to write it manually like: (with the hint on localeCompare from meskobalazs's comment)
var result = data.TrackingResults.sort(function(a,b){
return a.Products.Product[0].ProductName.localeCompare(b.Products.Product[0].ProductName)
});
This should work for sorting TrackingResults

Categories