Update only after all the checks are passed - javascript

I want to update array of object only after all the checks are passed. I have array of object representing all the articles and other array of object all the available stock.
I want to check the if all the articles are in stock then only I want to update the stock array. Here is my code:
const articles = [{
"id": "1",
"quantity": "4"
}, {
"id": "2",
"quantity": "8"
}, {
"id": "4",
"quantity": "1"
}];
let stock = [
{
"id": "1",
"stock": "6"
},
{
"id": "2",
"stock": "6"
},
{
"id": "3",
"stock": "2"
},
{
"id": "4",
"stock": "2"
}
];
articles.map(article => {
stock.map(item => {
if(item.id === article.id){
if(article.quantity <= item.stock){
item.stock = item.stock - article.quantity;
} else {
console.log('error');
throw error;
}
}
});
});
Problem with this solution is that it updates stock for id = 1 even though id = 2 is not enough. I am trying to check if all the articles are in stock are in enough quantity and update(minus) them in stock array. So in this case code will update stock array like this:
stock = [
{
"id": "1",
"stock": "2"
},
{
"id": "2",
"stock": "6"
},
{
"id": "3",
"stock": "2"
},
{
"id": "4",
"stock": "2"
}
];
Can someone suggest how can I fix this?

You can use Array.prototype.find(). Note: The snippet assumes that all articles have an "id" property, it doesn't check for "art_id".
const articles = [{
"id": "1",
"quantity": "4"
}, {
"id": "2",
"quantity": "8"
}, {
"id": "4",
"quantity": "1"
}];
let stock = [{
"id": "1",
"stock": "6"
},
{
"id": "2",
"stock": "6"
},
{
"id": "3",
"stock": "2"
},
{
"id": "4",
"stock": "2"
}
];
// Use Array.prototype.some() to check for items that don't have enough stock
const haveEnough = !articles.some(article =>
// Turns "1" into 1
parseInt(
// Find the stock with the same id as the article
stock.find(stock => stock.id === article.id).stock
) <
parseInt(article.quantity))
console.log(haveEnough)
You can then update the stock in
if (haveEnough) {
// Do something
}

I am assuming that the art_id key in the articles array should be id.
Unfortunately you can't do it all in one loop and you will instead have to loop through all the articles first to find out if their stock is enough and then loop though them again to change the existing stock:
const articles = [
{
id: '1',
quantity: '4',
},
{
id: '2',
quantity: '5',
},
{
id: '4',
quantity: '1',
},
];
let stock = [
{
id: '1',
stock: '6',
},
{
id: '2',
stock: '6',
},
{
id: '3',
stock: '2',
},
{
id: '4',
stock: '2',
},
];
// Are there any articles that do not have enough stock
const outOfStockArticles = articles.find((article) => {
const articleStock = stock.find((stock) => stock.id === article.id);
return Number.parseInt(article.quantity) > Number.parseInt(articleStock.stock);
});
// If there are no out of stock articles - change existing stock values
if (!outOfStockArticles) {
articles.forEach((article) => {
const articleStock = stock.find((stock) => stock.id === article.id);
articleStock.stock = Number.parseInt(articleStock.stock) - Number.parseInt(article.quantity);
});
}

There is an inconsistency in your articles array, I suppose that every articles has an "art_id", and not some an "id" and some an "art_id".
You can simply find your article using the Array.prototype.find function, and then by the isAvailable function check that an article is present in the right quantity in the stock list.
Now you can use the Array.prototype.every function that do exactly what you want! It will return true only if every element of the array satisfy the condition, in our case the isAvailable function.
Here a simple fiddle:
const articles = [{
"art_id": "1",
"quantity": "4"
}, {
"art_id": "2",
"quantity": "8"
}, {
"art_id": "4",
"quantity": "1"
}];
const stock = [{
"id": "1",
"stock": "6"
},
{
"id": "2",
"stock": "6"
},
{
"id": "3",
"stock": "2"
},
{
"id": "4",
"stock": "2"
}
];
const isAvaiable = (article) => {
return stock.find(element => element.id === article.art_id).stock >= article.quantity;
}
if (articles.every(isAvaiable)) {
console.log("I can update")
} else {
console.log("I cannot update")
}

Related

How can i filter result if i have array in body

i have a payload
{
"category": "Mobile",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
}
i want to find all object which have rating 1 or 2 or 3 and also have any location
Basically i am creating a filter for an ecommerce store i which we will get multiple location and multiple ratings as well so we will return only those object which have matched property. i am attaching a screenshot of UI for better understanding.
i want to run this filter with multiple location and multiple checked checkbox
You can do create a filter dynamically:
const { category, price, location, rating } = req.body;
const filter = {};
if (category) filter.category = category;
if (price) filter.price = { $gte: parseInt(price.from, 10), $lte: parseInt(price.to, 10) };
if (location?.length) filter.location = { $in: location };
if (rating?.length) filter.rating = { $in: rating };
const data = await Collection.find(filter);
If you want to filter your objects, you should use filter() from your array :
const arr = [{
"category": "Mobile1",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
},
{
"category": "Mobile2",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"2",
"3"
]
}];
const result = arr.filter(el => el.rating.includes("1") || el.rating.includes("2") || el.rating.includes("3"));
console.log(result);

How to group related fields in JSONL?

I am using Shopify's bulk operation mutation in GraphQL to fetch bulk data for products, invoices, transactions etc.
Shopify returns this data as JSONL. Each line is an object and if it is related to another item then it will have a __parentid which can be used to figure out its parent.
For example, the returned data will look something like this:
const data = [
{
id: "1",
__typename: "parent"
},
{
id: "2",
__parentId: "1",
__typename: "child"
},
{
id: "3",
__parentId: "2",
__typename: "grandChild"
},
{
id: "4",
__parentId: "2",
__typename: "grandChild"
}
]
In order to save this in my database, I need to nest each child value within its parent.
So the above would become
[
{
id: "1",
__typename: "parent",
child: [
{
id: "2",
__parentId: "1",
__typename: "child",
grandChild: [
{
id: "3",
__parentId: "2",
__typename: "grandChild"
},
{
id: "4",
__parentId: "2",
__typename: "grandChild"
}
]
}
]
},
]
This is one approach I tried where you can see I am trying to attach the children to the parent object and then once it has been moved, delete the original object.
export const reduceBulkResult = (chunks) => {
chunks.reverse()
chunks.forEach(chunk => {
const parent = chunks.find(node =>{
return node.id === chunk.__parentId
})
if( parent ) {
if( parent[chunk.__typename] ) {
parent[chunk.__typename].push(chunk)
} else {
parent[chunk.__typename] = [chunk]
}
}
})
return chunks;
}
console.log("reduceBulkResult", reduceBulkResult(data))
[
{
"__parentId": "2",
"__typename": "grandChild",
"id": "4"
},
{
"__parentId": "2",
"__typename": "grandChild",
"id": "3"
},
{
"__parentId": "1",
"__typename": "child",
"grandChild": [
{
"__parentId": "2",
"__typename": "grandChild",
"id": "4"
},
{
"__parentId": "2",
"__typename": "grandChild",
"id": "3"
}
],
"id": "2"
},
{
"__typename": "parent",
"child": [
{
"__parentId": "1",
"__typename": "child",
"grandChild": [
{
"__parentId": "2",
"__typename": "grandChild",
"id": "4"
},
{
"__parentId": "2",
"__typename": "grandChild",
"id": "3"
}
],
"id": "2"
}
],
"id": "1"
}
]
As you can see, there is a lof of duplication here and I need to get rid of the original objects some how and just keep the parent objects which have all the nested data.
I feel like I'm missing a trick here. There must be an easier way.
Shopify have some good tips such asReading the JSONL file in reverse makes it easier to group child nodes
I get the parent with filter() and then use recursive in getChildren to get the result.
I cannot find a simple way and you may change codes to make it more simple.
const data = [ { id: "1", __typename: "parent", }, { id: "2", __parentId: "1", __typename: "child", }, { id: "3", __parentId: "2", __typename: "grandChild", }, { id: "4", __parentId: "2", __typename: "grandChild", }, ]; const o = [ { id: "1", __typename: "parent", child: [ { id: "2", __parentId: "1", __typename: "child", grandChild: [ { id: "3", __parentId: "2", __typename: "grandChild", }, { id: "4", __parentId: "2", __typename: "grandChild", }, ], }, ], }, ];
const convert = data => {
const parent = data.filter(el => !el.__parentId);
const getChildren = (data, parentId) => {
let store = {};
for (const obj of data) {
if (obj.__parentId === parentId) {
const children = data.reduce((a, b) => {
if (b.__parentId === obj.id) {
if (a[b.__typename]) {
a[b.__typename].push({ ...b, ...getChildren(data, b.id) });
} else {
a[b.__typename] = [{ ...b, ...getChildren(data, b.id) }];
}
}
return a;
}, {});
store = { ...store, ...obj, ...children };
}
}
return store;
};
return parent.map(el => {
const children = data.reduce((a, b) => {
if (b.__parentId === el.id) {
if (a[b.__typename]) {
a[b.__typename].push({ ...b, ...getChildren(data, el.id) });
} else {
a[b.__typename] = [{ ...b, ...getChildren(data, el.id) }];
}
}
return a;
}, {});
return { ...el, ...children };
});
};
const output = convert(data);
console.log(output);

es6 create three dimensional array [duplicate]

This question already has answers here:
Build tree array from flat array in javascript
(34 answers)
Closed 2 years ago.
I have incoming data in this format:
const worldMap = [
{
"name": "Germany",
"parentId": null,
"type": "Country",
"value": "country:unique:key:1234",
"id": "1",
},
{
"name": "North Rhine",
"parentId": "1",
"type": "State",
"value": "state:unique:key:1234",
"id": "2",
},
{
"name": "Berlin",
"parentId": "1",
"type": "State",
"value": "state:unique:key:1234",
"id": "3",
},
{
"name": "Dusseldorf",
"parentId": "2",
"type": "city",
"value": "city:unique:key:1234",
"id": "4",
},
{
"name": "India",
"parentId": null,
"type": "Country",
"value": "country:unique:key:1234",
"id": "5",
},
];
I want the output to be something like this:
[
{
label: "Germany",
value: "country:unique:key:1234",
subs: [
{
label: "North Rhine",
value: "state:unique:key:1234",
subs: [
{
label: "Dusseldorf",
value: "city:unique:key:1234",
}
]
},
{
label: "Berlin",
value: "state:unique:key:1234",
}
]
}
,
{
"label": "India",
"value": "country:unique:key:1234"
}
]
Basically, it is a three dimensional array with first level being the Countrie, second States and third Cities. I have tried the following code:
let tempCountries = [];
worldMap.map((world) => {
if (world.parentId == null && world.type == "Country") {
tempCountries.push({label: world.name, value: world.value, id: world.id});
}
});
console.log("=== countries ===", tempCountries);
tempCountries.map((tempCountry) => {
const states = worldMap.find((x) => x.parentId == tempCountry.id);
console.log("=== states ===", states);
if (states !== undefined) {
}
});
In the first loop I got all the values for the countries. Next I am trying to append states and cities to the original countries, I got from the first loop. But I am not able to do so. The code should be verbose with minimum number of loops. Could anyone please help achieve this ?
Thanks
You could take a single loop and store all relations between child/parents and parents/childs.
const
data = [{ name: "Germany", parentId: null, type: "Country", value: "country:unique:key:1234", id: "1" }, { name: "North Rhine", parentId: "1", type: "State", value: "state:unique:key:1234", id: "2" }, { name: "Berlin", parentId: "1", type: "State", value: "state:unique:key:1234", id: "3" }, { name: "Dusseldorf", parentId: "2", type: "city", value: "city:unique:key:1234", id: "4" }, { name: "India", parentId: null, type: "Country", value: "country:unique:key:1234", id: "5" }],
tree = ((data, root) => {
var t = {};
data.forEach(({ id, parentId, name: label, value }) => {
Object.assign(t[id] = t[id] || {}, { label, value });
t[parentId] = t[parentId] || {};
(t[parentId].subs = t[parentId].subs || []).push(t[id]);
});
return t[root].subs;
})(data, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript array equality control

Hi I have two changeable length arrays and I tried If there is no value I want, delete it from that array
array1 = [
{
"serial": "3",
"code": "1"
},
{
"serial": "700",
"code": "1"
},
{
"serial": "300",
"code": "1"
},
{
"serial": "400",
"code": "1"
}
]
array2 = [{
"someting": 10,
"someting2": "20",
"serialList": ["700","711"],
},
{
"someting": 10,
"someting2": "30",
"serialList": ["300"],
},
{
"someting": 0,
"someting2": "0",
"serialList": [],
}
]
this my two array as I said arrays length is changeable sometimes array1 length big, sometimes array2 and I want If serial number in array1 does not exist in array2 delete from array1 element,
according to above array1[0] and array1[3] serial codes does not exist any element of array2 I want to output array1 is:
array1 = [
{
"serial": "700",
"code": "1"
},
{
"serial": "300",
"code": "1"
}
]
How can I do that, thnx
here is a simple and readable approach to achieve that
let allowedSerials = array2.map( obj=> obj.serialList ).flat();
let result = array1.filter( obj => allowedSerials.includes(obj.serial) )
check the snippet below:
let array1 = [
{
"serial": "3",
"code": "1"
},
{
"serial": "700",
"code": "1"
},
{
"serial": "300",
"code": "1"
},
{
"serial": "400",
"code": "1"
}
]
let array2 = [{
"someting": 10,
"someting2": "20",
"serialList": ["700","711"],
},
{
"someting": 10,
"someting2": "30",
"serialList": ["300"],
},
{
"someting": 0,
"someting2": "0",
"serialList": [],
}
];
// straight-forward solution:
let allowedSerials = array2.map( obj=> obj.serialList ).flat();
let result = array1.filter( obj => allowedSerials.includes(obj.serial) )
console.log(result);

Nested JSON - Join sub-object

How can I remove sub-objects?
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}]
}]
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory_2kg": "5",
"current_inventory_5kg": "5",
"current_inventory_10kg": "5",
"current_inventory_20kg": "5",
}]
Use Object.keys() and a forEach loop
var x =[
{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [
{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}
]
}
]
x[0].current_inventory.forEach(e=>{
Object.keys(e).forEach(j=>{
x[0]['current_inventory_'+j]=e[j];
})
delete x[0].current_inventory
})
console.log(x)
Use Object.entries and reduce will simplify.
const data = [
{
id: "1",
desc: "SOME PRODUCT",
codigo: "CODE-28",
codigoBarras: "2000000001",
unidade: "PCT",
price: "24.15",
current_inventory: [
{
"2kg": 5,
"5kg": 5,
"10kg": 5,
"20kg": 5,
productId: 1
}
]
}
];
const [first] = data;
const updated = Object.entries(first).reduce((acc, [key, value]) => {
if (Array.isArray(value)) {
value.forEach(item =>
Object.entries(item).forEach(
([cKey, cValue]) => (acc[`${key}_${cKey}`] = cValue)
)
);
} else {
acc[key] = value;
}
return acc;
}, {});
console.log(updated);
THANK YOU VERY MUCH!!!
Solved using the code below:
data is de object
estoqueFracionado is the sub-object
for (let [key, value] of Object.entries(data)) {
value.estoqueFracionado.forEach (e => {
Object.keys(e).forEach(j => {
value['estoqueFracionado_' + j] = e[j]
})
delete value.estoqueFracionado
})
}

Categories

Resources