Angular - Search for multiple keys inside array of objects - javascript

The array of objects:
array = [
{
"id": 1,
"key": "key1",
"name": "name1",
"area": "area1",
"functionalArea": "func1",
"lob": "lob1",
},
{
"id": 2,
"key": "key2",
"name": "name2",
"area": "ALL",
"functionalArea": "ALL",
"lob": "ALL",
},
]
My atempt:
const { name, id, functionalArea, area, lob } = this.form.getRawValue();
const searchTerms = {
widgetName,
widgetId,
functionalArea,
area,
lob,
};
.subscribe(
(res) => {
let results = array.filter((item) =>
searchTerms.functionalArea === 'ALL' &&
searchTerms.area === 'ALL' &&
searchTerms.lob === 'ALL' &&
!searchTerms.id &&
!searchTerms.name
? item
: item.key.toLowerCase().includes(searchTerms.widgetId.toLowerCase()) ||
item.name.toLowerCase().includes(searchTerms.widgetName.toLowerCase()) ||
(item.functionalArea.toLowerCase().includes(searchTerms.functionalArea.toLowerCase()) &&
item.area.toLowerCase().includes(searchTerms.area.toLowerCase()) &&
item.lob.toLowerCase().includes(searchTerms.lob.toLowerCase()))
);
},
The problem:
I cannot filter for multiple conditions using includes() function, it does not work.
If i remove all conditions and use only one than the includes() function works.

A filter is a function that return true or false, As always you want to "search" is good at first convert to upperCase (or lowerCase) the "condition"
searchTerms.functionalArea=searchTerms.functionalArea?
searchTerms.functionalArea.toLowerCase():'ALL'
searchTerms.area =searchTerms.functionalArea?
searchTerms.area.toLowerCase():'ALL'
searchTerms.lob =searchTerms.functionalArea?
searchTerms.lob.toLowerCase():'ALL'
searchTerms.name=searchTerms.name?
searchTerms.name.toLowerCase():'ALL'
const result=array.filter((item)=>{ //<--see this bracket
let result=searchTerms.functionalArea=='ALL' ||
searchTerms.functionalArea.includes(item.functionalArea.toLowerCase());
result=result && (searchTerms.area =='ALL' ||
searchTerms.area.includes(item.area .toLowerCase());)
result=result && (searchTerms.lob =='ALL' ||
searchTerms.lob.includes(item.lob .toLowerCase());)
//Update
result=result && (!searchTerms.widgetId ||
searchTerms.widgetId==item.id)
result=result && (!searchTerms.widgetName ||
searchTerms.widgetName.includes(item.name.toLowerCase());)
return result; //<--as you use bracket, you should use return
})

You have to filter only if the conditions about searchTerm are true, something like this:
let results = (searchTerms.functionalArea === 'ALL' &&
searchTerms.area === 'ALL' &&
searchTerms.lob === 'ALL' &&
!searchTerms.id &&
!searchTerms.name)
? array
: array.filter((item) => item.key.toLowerCase().includes(searchTerms.widgetId.toLowerCase()) ||
item.name.toLowerCase().includes(searchTerms.widgetName.toLowerCase()) ||
(item.functionalArea.toLowerCase().includes(searchTerms.functionalArea.toLowerCase()) &&
item.area.toLowerCase().includes(searchTerms.area.toLowerCase()) &&
item.lob.toLowerCase().includes(searchTerms.lob.toLowerCase())));
EXAMPLE (check the console output): https://stackblitz.com/edit/typescript-y2w6sr?file=index.ts

Related

check if keys exist in object and if it has value

How do we check the keys and compare it to the data object , if one or more keys from the keys array does not exist in object data or if it exist or key exists and the key value has no value or null or undefined then return false else return true.
For example keys has a key summary and it exists on object data but the value is empty so it should return false;
I've tried Object.keys and used includes but cant seem to work it out, maybe someone has an idea. Thanks.
#currentCode
const sample = Object.entries(sampleOject).some((value) => {
return keys.includes(value[0]) ? false : (value[1] === null || value[1] === "");
})
Thanks.
#keys
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission']
#sample object data
{
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary: ""
}
You could use every() with hasOwnProperty and additional checks for empty strings etc
const result = keys.every(key => {
return data.hasOwnProperty(key) && data[key] !== ''
}, {});
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission'
];
const data = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": ""
};
const result = keys.every(key => {
return data.hasOwnProperty(key) && data[key] !== ''
}, {});
console.log(result); // False
I just optimized your code.
const sample = Object.entries(sampleOject).map(([key, value]) => {
return keys.includes(key) ? value ? true : false : false;
})
...
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission']
const obj = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": "test"
}
let arr = [];
const result = Object.entries(obj).map(([key, val]) => {
if (keys.includes(key)) {
if ((val !== '') && (val !== 'undefined') && (val !== 'null') ) {
return true;
} else {
return false;
}
} else {
return false;
}
})
const getValue = result.includes(true);
console.log(getValue)
My approach would be to check whether all keys are present in data with the help of .every.
Also non-strict != will check if certain key contain neither null nor undefined
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission'];
const data = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": ""
};
const check = (obj, keys) => keys.every((key) =>
key in obj && obj[key] != undefined);
console.log(check(data, keys));
According to mdn,
const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car); // output: true

How to add and remove values from local storage on checkbox click in Angular8

i have dynamic generated list of checkbox, i want to create array with objects.
I wanted to push data in array of objects if value is true and setItem to localStorage,
and if value is false then it will remove objects from local storage
Can anyone help me to optmize my code with expected output.
Expected output
[
{
"key": "Test",
"value": true
},
{
"key": "Test1",
"value": true
},
{
"key": "removeItem",
"value": false
}
]
Code
setColumn($event, item) {
var obj = {}, valueAliasPair = [];
if (item.tabelHeader.data != '' && $event.checked === true) {
obj['key'] = item.tabelHeader.data;
obj['value'] = $event.checked;
valueAliasPair.push(obj);
localStorage.setItem('AvailableAmt', JSON.stringify(valueAliasPair));
}
if (item.tabelHeader.data != '' && $event.checked === false) {
localStorage.removeItem('AvailableAmt', obj['key']);
}
console.log(valueAliasPair, "valueAliasPair");
}
Updated:
setColumn($event, item) {
let valueAliasPair = JSON.parse(localStorage.getItem("AvailableAmt") || "[]");
if (item.tabelHeader.data != "") {
if ($event.checked) {
valueAliasPair.push({
key: item.tabelHeader.data,
value: true,
});
localStorage.setItem("AvailableAmt", JSON.stringify(valueAliasPair));
} else {
const ind = valueAliasPair.findIndex((x) => x.key === item.tabelHeader.data);
valueAliasPair.splice(ind, 1);
localStorage.setItem("AvailableAmt", JSON.stringify(valueAliasPair));
}
}
console.log(valueAliasPair, "valueAliasPair");
}

Javascript Filtering on Null Values

I am filtering this list
[
{
appLearningItemId: 67
catalogues: (2) [ {id: 1041, value: "New Catalog"},
{id: 1058, value: "Test"}]
categories: (3) [{id: 1, value: "Soft Skills"},
{id: 3, value: "Non-technical"},
{id: 5, value: "Induction"}]
code: "CCE0013"
suppliers: (3) [{id: 1, value: "Company XYZ Ltd"},
{id: 2, value: "test c2"},
{id: 17, value: "new company"} ]
title: "07 Values & Beliefs"
type: {id: 11377, value: "Elearning"}
}, ... * 682 items
]
with this object and filter
const filters = {
type: 'Elearning',
catalog: 1041,
category: 1,
supplier: 1
}
let advancedFilteredLearningItems = this.originalLearningItems.filter(obj => obj.type.value == filters.type
&& obj.catalogues.some( catalogs => catalogs.id == filters.catalog)
&& obj.categories.some( category => category.id == filters.category)
&& obj.suppliers.some(supplier => supplier.id === filters.supplier));
console.log(advancedFilteredLearningItems)
which works great. Sometimes the filter object will have a null value in some or up to 3 of the values eg:
const filters = {
type: 'Elearning',
catalog: null,
category: 1,
supplier: null
}
how do I edit the filter code to not filter on null items so in this case I get back all E-learning items with a category of 1? Currently the filter code is looking for null values but I just want to omit it from the filter completely.
Would adding a null check to all of your filters work? So if it is null you return true because you want all of the catalogs before it? This isn't the most efficient solution, but it should get you to where you need.
const filters = {
type: 'Elearning',
catalog: 1041,
category: null,
supplier: null
}
let advancedFilteredLearningItems = this.originalLearningItems.filter(obj =>
(filters.type != null ? obj.type.value == filters.type : true)
&& obj.catalogues.some(catalogs => filters.catalog != null ? catalogs.id == filters.catalog : true)
&& obj.categories.some(category => filters.category != null ? category.id == filters.category : true)
&& obj.suppliers.some(supplier => filters.supplier != null ? supplier.id === filters.supplier : true));
console.log(advancedFilteredLearningItems)
EDIT:
A more efficient solution is to not loop through your catalogues if there is no filter. This can be done by adding an extra function
let advancedFilteredLearningItems = this.originalLearningItems.filter(obj =>
(filters.type != null ? obj.type.value == filters.type : true)
&& this.filterItems(filters.catalog, obj.catalogs)
&& this.filterItems(filters.categories, obj.categories)
&& this.filterItems(filters.supplier , obj.suppliers)
console.log(advancedFilteredLearningItems)
// new function
filterItems(filter, array) {
if (filter == null) {
return true;
}
return array.some(item => item.id == filter);
}
EDIT 2: In case you don't want to add a new function, this should be as efficient as my first edit
let advancedFilteredLearningItems = this.originalLearningItems.filter(obj =>
(filters.type == null || obj.type.value == filters.type)
&& (filters.catalog == null || obj.catalogues.some(catalogs => catalogs.id == filters.catalog))
&& (filters.categories == null || obj.categories.some(category => category.id == filters.category))
&& (filters.supplier == null || obj.suppliers.some(supplier => supplier.id == filters.supplier))
);

Angular: How to get the values of the array of objects

I am trying to get the values of the array of objects using filer in angular but unable to find the solution. Most probably missing something.
channels: {
"channelId": 18,
"platforms": [
{
"name": "android",
"isRecordable": "Y",
},
{
"name": "ios",,
"isRecordable": "Y",
},
{
"name": "pctv",
"isRecordable": "Y",
},
{
"name": "pctv",
"isRecordable": "Y",
},
{
"name": "stb",
"multicastIp": "224.0.251.1",
"multicastPort": 8002,
"isRecordable": "Y"
}
]
}
I want to get the value of a multicast ip where platformName = stb and multicastIp should not be null.
Can someone please explain how to do it.
Use the filter() and find() JavaScript array methods.
//Your array
const platforms = channelConfig.platforms;
const arr = plaforms.filter(platform => { return platform.multicastIp != undefined && platform.name == 'stb' });
let multiCastIps = []
channelconfig.platforms.forEach((platform) => {
if(platform.name == 'stb' && platform.multicastIp != null){
multiCastIps.push(platform)
// pushing only the platforms where name = stb and mltucastip != null
}
});
Short way:
let multiCastIps= channelconfig.platforms.filter(platform => { return platform.name == 'stb' && platform.multicastIp != null});
I would do it like this:
const STB_PLATFORM = "stb";
const stbPlatform = channels.platforms.find(p => p.name == STB_PLATFORM && !!p.multicastIp);
let multicastIP = stbPlatform ? stbPlatform.multicastIp : "Not Available";
The STB_PLATFORM could be a parameter to a search function or a component constant.

Search in array of objects that sits in object in array

I need to check if bidder "one" already has "placementId": "4" in arr.
I've tried to combine for loop with filter with no luck. Is there any elegant way to solve this?
var check = { "one": "4" },
arr = [{
"code": "qwe",
"bids": [{
"bidder": "one",
"params": {
"placementId": "1"
}
},
{
"bidder": "two",
"params": {
"placementId": "2"
}
}
]
}, {
"code": "asd",
"bids": [{
"bidder": "one",
"params": {
"placementId": "3"
}
}]
}];
I think find() is the way to go here. You want to find an element in your array where one of the bids has a bid.bidder of "one" and bid.params.placementId of 4. Or undefined if it doesn't exist.
This can be expressed in javascript with something like:
let found = arr.find(code =>
code.bids.some(bid => bid.bidder === "one" && bid.params.placementId === "4"))
Since you only want to know whether it exists or not you basically only care if it returns something or undefined. Here's a positive and negative example:
var check = { "one": "1" },arr = [{"code": "qwe","bids": [{"bidder": "one","params": {"placementId": "1"}},{"bidder": "two","params": {"placementId": "2"}}]}, {"code": "asd","bids": [{"bidder": "one","params": {"placementId": "3"}}]}];
// user one placement id 4 does not exist
let found = arr.find(code => code.bids.some(bid => bid.bidder === "one" && bid.params.placementId === "4"))
console.log(found !== undefined)
// user two placement id 2 does exist
found = arr.find(code => code.bids.some(bid => bid.bidder === "two" && bid.params.placementId === "2"))
console.log(found !== undefined)
Use this code:
arr.forEach(element => {
element.bids.forEach(item=>{
if(item.bidder == Object.keys(check)[0]){
if(item.params.placementId == 1){
console.log("bidder 1 and placementId 1 found");
}
}
});
});
var bidders = {};
arr.forEach((field)=>{
let bidArray = field.bids.map((bids)=>{
if(bidders[bids.bidder] === undefined){
bidders[bids.bidder] = []
}
return {bidder:bids.bidder,placementId:bids.params.placementId};
})
for(let placement of bidArray){
bidders[placement.bidder].push(placement.placementId);
}
})
console.log(bidders);
To list out all the bidders and their respective placements
then you can do
if(bidders.one.indexOf(4) !== -1){
console.log('Placement 4 is taken by bidder 1.');
}
else{
console.log('Placement 4 is not taken by bidder 1.');
}

Categories