JSON - make subchild as a condition for IF Statement - javascript

I have a JSON from an API with this content:
"items":[
{
id: *id here*,
variant: {
variant_name: *name here*,
variant_id: *id here*,
stores: {
0:
store_id: *STOREID1*,
available_for_sale: true
1:
store_id: *STOREID2*,
available_for_sale: true
}
}
}]
I want to select the items with the same store ID and Available for sale status. I have tried this but this isn't working:
if(items.variant.stores.store_id === "STOREID1" && items.variant.stores.available_for_sale === 'true'){
But it says
Uncaught TypeError: Cannot read property 'store_id' of undefined
EDIT:
I tried this:
if(items.variants.stores.store_id["******"] && items.variants.stores.available_for_sale['true']){
But it still gives the same error.
EDIT 2:
Edited the Question for more clarification.

Your JSON file is malformed. I've tried to fix it to be valid. Next time take the object you get in the console.log, and instead use JSON.stringify(jsobject) for valid JSON output instead of trying to copy paste it verbatim.
It's not entirely clear if you want the whole object, or just the stores values. But I've implemented both.
I've used Object.values, because your notation looks like objects (which would make it invalid JSON), but if they are really arrays, you shouldn't need Object.values.
data = {
"items": [{
id: "*id here*",
variant: {
variant_name: "*name here*",
variant_id: "*id here*",
stores: {
0: {
store_id: "*STOREID1*",
available_for_sale: true
},
1: {
store_id: "*STOREID2*",
available_for_sale: true
}
}
}
}]
}
// filter for and return whole object for any that have the stores in question
// use some to to search for at least one match of store values
console.log(
data.items.filter(item => Object.values(item.variant.stores).some(({
store_id,
available_for_sale
}) => store_id === '*STOREID1*' && available_for_sale))
)
// get stores values
// Using flatMap to combine all the arrays returned from each stores object.
console.log(
data.items.flatMap(item => Object.values(item.variant.stores).filter(({
store_id,
available_for_sale
}) => store_id === '*STOREID1*' && available_for_sale))
)

items is an array, you need to iterate over it and filter the items you want
const items = [{
id: 1,
variant: {
variant_name: '*name here*',
variant_id: 111,
stores: { store_id: 1111, available_for_sale: true }
}
},
{
id: 2,
variant: {
variant_name: 'name here',
variant_id: 222,
stores: { store_id: 2222, available_for_sale: true }
}
}
];
const result = items.filter(({variant: v}) => (
v.stores.store_id === 2222 && v.stores.available_for_sale
));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Find the difference between two arrays based on some the value inside a nested array

I have two arrays
arrayOfItems: [
{
id: '4321-3321-4423',
value: 'some text'
},
{
id: '4322-4654-9875',
value: 'some text again'
}
]
Then the second array
itemX: [
{
id: '3214-6543-4321',
nestedArrayOfItems:[
{id: '4321-3321-4423'}
{id: '3455-8765-7764'}
]
}
]
I need to create a new array based on arrayOfItems that doesn't include any of the id's in the itemX.nestedArrayOfItems
Because of it being a nested Array I'm drawing a blank on what I need to do... I'm searching through Lodash to see if there is something that doesn't involve me using a bunch of for loops.
You can use Array.prototype.filter() and then check if the id exists with
Array.prototype.some() like so:
const arrayOfItems = [
{
id: '4321-3321-4423',
value: 'some text'
},
{
id: '4322-4654-9875',
value: 'some text again'
}
]
const itemX = [
{
id: '3214-6543-4321',
nestedArrayOfItems: [
{id: '4321-3321-4423'},
{id: '3455-8765-7764'}
]
}
]
const res = arrayOfItems.filter(item => !itemX[0].nestedArrayOfItems.some(({ id }) => id === item.id))
console.log(res);
how about this :
let difference = arrayOfItems.filter(x => ! itemX.nestedArrayOfItems.includes(x));
PS : ids must be string

Javascript - transform an object of array list to another format?

So I've been stumped on this for hours and I can't really figure out an elegant solution to solve this problem. Let's say I have this:
let Fields = {
GAME: [
{ code: '{{GTAV}}', title: { en: "grnti"} },
{ code: '{{GTA5}}', title: { en: "Grand theph " } },
]
};
How can I turn this into a new format that looks like this ?
let Fields = {
tags: [
{ name: 'GAME', tags:[
{ name: 'grnti', value: "{{GTAV}}" },
{ name: 'Grand theph', value: "{{GTA5N}}" }
]},
]};
I tried to create a function to do the job , but for some reason my brain cannot seem to grasp the solution. Any help please !
A simple version of this might look like the following:
const transform = (fields) => ({
mergeTags: Object .entries (fields) .map (([name, innerFields]) => ({
name,
mergeTags: innerFields .map (({code, title: {en}}) => ({name: en, value: code}))
}))
})
const fields = {RECIPIENT: [{code: '{{RECIPIENT.LN}}', title: {en: "name"}}, {code: '{{RECIPIENT.FN}}', title: {en: "first name" }}]}
console .log (transform (fields))
But from your nested mergeTags properties, I'm guessing that there is something recursive going on. If so, we need more information about the input and output structures.
i just threw a nested reduce function together.
const transformed = Object.entries(Fields).reduce((tags, [key, value]) => {
const mergedTags = value.reduce((codes, code) => {
codes.mergeTags.push({name: code.title.en, value: code.code});
return codes;
}, {name: key, mergeTags: []})
tags.mergeTags.push(mergedTags)
return tags;
}, {mergeTags: []})
Does that work for you?
It is hard to tell exactly from your question what you are hoping to accomplish as well as the shape of your data. Based on your question though, you would probably want to use the Object.keys and map functions
let Fields = {
RECIPIENT: [
{ code: '{{RECIPIENT.LN}}', title: { en: "name" } },
{ code: '{{RECIPIENT.FN}}', title: { en: "first name" } },
]
};
// gets the keys of the 'Fields' object(in this case only 'RECIPIENT'
let newFields = Object.keys(Fields)
// each key should create a new object with the 'key' from the original object as the 'name' of the new object
.map(key => ({
name: key,
// 'Fields[key]' gets the array from the 'RECIPIENT' property and then creates a new object from each object in the original array, mapping the 'title.en' property in the original object to 'name' in the new object and 'code' in the original object to 'value' in the new object
mergeTags: Fields[key].map(property => ({
name: property.title.en,
value: property.code
}))
}));
console.log(newFields);
Here's a clean way that may seem a bit like magic, but I'll walk you through what's going on.
let Fields = {
RECIPIENT: [
{ code: '{{RECIPIENT.LN}}', title: { en: "name"} },
{ code: '{{RECIPIENT.FN}}', title: { en: "first name" } },
]
};
const { pipe, fork, map, get } = rubico
const Transformed = pipe([
Object.entries, // { RECIPIENT: [...] } => [['RECIPIENT', [...]]
fork({
mergeTags: map(fork({ // iterate through each entry ['RECIPIENT', [...]]
name: get(0), // name is the item at index 0 of each entry
mergeTags: pipe([
get(1), // mergeTags starts with index 1 of each entry, the array of code+title objects
map(fork({ // iterate through the array of code + title objects and create new objects
name: get('title.en'), // name is title.en of each object
value: get('code'), // value is title.code of each object
})),
]),
})),
}),
])(Fields)
console.log(JSON.stringify(Transformed, null, 2))
<script src="https://unpkg.com/rubico"></script>
Disclaimer: I am the author of rubico
You can examine these methods in depth at the documentation

How can i display more than one array elements that satisfy a condition?

How can I display multiple values of an array to the console that match the condition (e.g: === "McDonalds")?
I only managed to display one item. But I don't know how i can display all the value of my array.
public products: product[] = [
{ id: 1, name: "McFlurry", price: 2, enseigne:"McDonalds" },
{ id: 2, name: "Potatoes", price: 3, enseigne:"McDonalds" },
{ id: 3, name: "BigMac", price: 4, enseigne:"KFC" },
{ id: 4, name: "Nuggets", price: 3, enseigne:"KFC" }
];
searchEnseigne(){
let server = this.products.find(x => x.enseigne === "McDonalds");
console.log(server);
}
let server = this.products.filter(x => x.enseigne === "McDonalds");
console.log(server);
Use filter instead of find:
The filter() method creates a new array with all elements that pass the test. While The find() method returns the value of the first element
searchEnseigne(){
let server = this.products.filter(x => x.enseigne === "McDonalds");
console.log(server);
}

how to output keys in a key value pair within nested arrays using constructor Javascript

Within the array of 'items' I wanted to output within the 'info' array only the keys: [ 'stringTwo', 'StringThree' ]
and also output the value String Three
let items = [
{
string: 'string1',
info:
{
stringTwo:'String Two',
stringThree: 'String Three'
},
size:3445
},
{
string: 'string2',
info: 'ruby files'
},
{
string: 'string3',
info: ''
},
{
string: 'string4 without info key',
}
];
I tried with both of these codes:
data.forEach((data) => {
if(data.info.constructor === Object) {
console.log(Object.keys(data.info));
}
})
data.forEach((data) => {
if(data.info.constructor === Object) {
console.log((data.info.stringThree));
}
})
the first one should output the Keys [ 'stringTwo', 'StringThree' ]
and the second one should output String Three
I'm wondering why in a more larger scale array that has more key-value pairs both doesn't work and gives me an input of TypeError: Cannot read property 'constructor' of undefined?
if so are there other ways without using constructor?
Your larger scale array probably don't have any info key. To prevent having an error, you should :
Change your items array to put an info key, even empty
or
Add a typeof data.info !== "undefined" condition to check if the info key is defined on each item before trying to access it.
Here is a working example :
let items = [
{
string: 'string1',
info:
{
stringTwo:'String Two',
stringThree: 'String Three'
},
size:3445
},
{
string: 'string2',
info: 'ruby files'
},
{
string: 'string3',
info: ''
},
{
string: 'string4 without info key',
}
];
items.forEach((data) => {
if(typeof data.info !== "undefined" && data.info.constructor === Object) {
console.log(data.info.stringThree);
}
})

Map or Each for Values with Underscore.js

I am trying to figure out the best way to update my underscore.js .map method since the inclusion of a new field value that should be grouped with the current value being passed to .map. Should I use .map or .each with the new update and should I store the values as an object or object in an array and pass that to the .map or .each to achieve my desired outcome? At the moment I tried the object approach with .map, but the values are coming through as arrays.
Proper format:
[ { reportTitle: 'Title1', reportLink: 'test.com', id: 166 },
{ reportTitle: 'Title2', reportLink: 'test2.com', id: 166 } ]
Original (Working):
var links = _.map(req.body.reportLink, function(link){
return {
reportLink: link,
id: blog.id
};
});
Output:
[ { reportLink: 'test.com', id: 166 },
{ reportLink: 'test2.com', id: 166 } ]
Updated (Not Working):
var linkAttributes = { title: req.body.reportTitle, link: req.body.reportLink}
var links = _.map(linkAttributes, function(link) {
return {
reportTitle: link.title,
reportLink: link.link,
id: blog.id
};
});
Output:
[ { reportTitle: [ 'Test 1', 'Test 2' ],
reportLink: [ 'test1.com', 'test2.com' ],
id: 164 } ]
It is now clear what it is you're asking, the following should do the trick:
const zip = (arr1, arr2) =>
[...new Array(Math.max(arr1.length, arr2.length))].map(
(_, i) => [arr1[i], arr2[i]],
);
const reportTitle = ['test-title', 'test-title2'];
const reportLink = ['test.com', 'test2.com'];
console.log(
zip(reportTitle, reportLink).map(
([reportTitle, reportLink]) => ({
reportTitle,
reportLink,
id: 166,
}),
),
);
The zip utility takes 2 arrays (for example [1,2,3] and [5,6,7]) and returns an array with an element from each array: ([[1,5],[2,6],[3,7] from the example)
Then it maps over this array to create an array of objects.
The function passed to map uses destructuring parameters to quickly name the 2 elements from the array passed to the map function.
_.map -> shoud have first argument as array
var linkAttributes = [
{
title: req.body.reportTitle,
link: req.body.reportLink
}
]; // shoud be array
var links = _.map(linkAttributes, function(link) {
return {
reportTitle: link.title,
reportLink: link.link,
id: blog.id
};

Categories