Check if the property exist in array - javascript

The name attribute_name:"position" is very rare and I want to check that if the property exists I want to push it to the new array. However, every time I try to add a condition it gives me errors.
[0].attribute_name inside the for loop is giving me trouble. There may or may not be two arrays inside activity_attributes. But I want to make a call bases on first array, if the itemloop[i].activity_attributes[0].attribute_name push them to new array.
if(res.status == "success") {
var itemloop = res.response.activities;
var social_post_link = [];
for(var i=0; i<itemloop.length; i++){
if(itemloop[i].activity_attributes[0].attribute_name == "position") {
social_post_link.push(itemloop[i].activity_attributes);
}
}
console.log(social_post_link);
}

You can use if('attribute_name' in yourObject) to achieve that.
Demo.
var res = {
status: 'success',
response: {
activities : [
{
activity_attributes: [
{
attribute_name: 'position'
}
]
},
{
activity_attributes: [
{
test: 'test'
}
]
}
]
}
};
if(res.status == "success") {
var itemloop = res.response.activities;
var social_post_link = [];
for(var i=0; i<itemloop.length; i++){
if( 'attribute_name' in itemloop[i].activity_attributes[0]){ //HERE
if(itemloop[i].activity_attributes[0].attribute_name == "position") {
social_post_link.push(itemloop[i].activity_attributes);
}
}
}
console.log(social_post_link);
}

Use should use the hasOwnProperty method
if(itemloop[i].activity_attributes[0].hasOwnProperty('attribute_name') && itemloop[i].activity_attributes[0].attribute_name == "position")
You code should be like
if(res.status == "success") {
var itemloop = res.response.activities;
var social_post_link = [];
for(var i=0; i<itemloop.length; i++){
if(itemloop[i].activity_attributes[0].hasOwnProperty('attribute_name') && itemloop[i].activity_attributes[0].attribute_name == "position") {
social_post_link.push(itemloop[i].activity_attributes);
}
}
console.log(social_post_link);
}

Array.prototype.filter() and Array.prototype.map() can be combined to construct new arrays based on predicated rules such as attribute_name == 'position' and return child values.
See below for a practical example.
if (res.status == 'success') {
const itemloop = res.response.activities
const social_post_link = itemloop.filter(x => x.attribute_name == 'position').map(x => x.activity_attributes)
console.log(social_post_link)
}

instead of activity_attributes[0].attribute_name ,try using activity_attributes[0]['attribute_name'] == 'position'

Related

Array in localStorage is not initialized at first run

window.reload = () => {
var userArray = JSON.parse(localStorage.getItem("key"));
}
let feedback = document.getElementById("feedback");
function checkemail(userArray, email) {
var i;
if (userArray == null | undefined) {
userArray = JSON.parse(localStorage.getItem("key"));
}
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value
};
let isFound = false;
for (i = 0; i < userArray.length; i++) { //here is the error it still happen even after I added the if null part
if (userArray != undefined)
var oldemail = userArray[i].email;
let newemail = document.getElementById("emailinput").value;
if (newemail === oldemail) {
isFound = true;
i = userArray.length;
return feedback.innerHTML = "email exist please log in or register with different email";
}
}
if (!isFound) {
return storeName(person, userArray);
}
}
function storeName(person, userArray) {
if (userArray != undefined)
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value
};
userArray = JSON.parse(localStorage.getItem("key"));
userArray.push(person);
userArray = JSON.stringify(userArray);
localStorage.setItem("key", userArray);
console.log(userArray);
}
I want to store an array in local storage, the first time when I run the code, of course, the array is empty and I can not use a loop for example because I can't call (array.length).
so can I tell the compiler for example if the array is null or undefined just put length is zero or assign the value of the array to an empty array?
can I do something like this?
if( userArray == null | undefined) { userArray = JSON.parse(localStorage.getItem("key")); }
function checkemail(userArray, email) {
if (userArray == null || typeof(userArray) == 'undefined') {
userArray = [];
}
// rest of the code
}
This might be working too:
userArray ??= [];

Find in object to Edit or Add

I have an object productCounts
[{provisioned=2.0, product=str1, totalID=1.0},
{product=str2, provisioned=4.0, totalID=3.0},
{provisioned=6.0, product=str3, totalID=5.0}]
I have an array uniqueProduct
[str1, str2, str3, str4]
I am then looping a dataset to get the totalID count, add it to the product's totalID but if it doesn't exist, push it to the object.
var countID = 0;
uniqueProduct.forEach(
currentproduct => {
countID = 0;
for (var i = 0; i < shtRng.length; ++i) {
if (shtRng[i][ProductCol].toString() == currentproduct) { // && shtRng[i][IDcol].toString().length>4){
countID++;
}
}
if (countID == 0) {
return;
}
console.log(currentproduct + ": " + countID);
}
)
This works perfectly to return the countID per product in uniqueProduct
Rather than logging the result, I would like to add it to the object like this... If the current unique product is not in the productCounts object, add it.
let obj = productCounts.find((o, i) => {
if (o.product == currentproduct) {
productCounts[i] = { product: currentproduct, totalID: productCounts[i].totalID+countID, provisioned: productCounts[i].provisioned };
return true;
} else {
productCounts.push({ product: currentproduct, totalID: countID, provisioned: 0 });
return true;
}
});
In my head, this should work but it appears to skip some records or add the product multiple times. How do I add to the object correctly?
Expected output is the object to be something similar to:
[{provisioned=2.0, product=str1, totalID=35.0},
{product=str2, provisioned=4.0, totalID=8.0},
{provisioned=6.0, product=str3, totalID=51.0},
{provisioned=6.0, product=str4, totalID=14.0}]
The argument to find() is a function that returns a boolean when the element matches the criteria. The if statement should use the result of this, it shouldn't be in the condition function.
let obj = productCounts.find(o => o.product == currentProduct);
if (obj) {
obj.totalId += countID;
} else {
productCounts.push(productCounts.push({ product: currentproduct, totalID: countID, provisioned: 0 });
}
BTW, your life would be easier if you used an object whose keys are the product names, rather than an array of objects. You can easily turn the array of objects into such an object:
let productCountsObj = Object.fromEntries(productCounts.map(o => [o.product, o]));
if (currentProduct in productCountsObj) {
productCountsObj[currentProduct].totalID += countID;
} else {
productCountsObj[currentProduct] = { product: currentproduct, totalID: countID, provisioned: 0 };
}

Grouping by fields after reduce is not working in JavaScript

There is a complex object and based on an array which is given as an input I need to modify its properties. Illustration is shown below. If the "field" is same , add them to "or" array .If its different "field" add them to "and" array along with its "value". I am using Set to get keys from both source and input and using them to group based on its keys. Also whenever there are duplicates .ie., suppose the "filterObj" already has the same (field, value) pair. Be it in "and" or inside "or",Then don't add it in the final object
Sandbox: https://codesandbox.io/s/optimistic-mirzakhani-pogpw-so-dpvis
There is a TestCases file in the sandbox which its needs to pass
let filterObj = {
feature: "test",
filter: {
and: [{ field: "field2" }]
}
};
let obj = [{ field: "field2", value: "3" }];
let all_filters = [];
if (filterObj.filter.and && filterObj.filter.and.hasOwnProperty("or")) {
all_filters = [...filterObj.filter.and.or];
} else if (filterObj.filter.and) {
all_filters = [...filterObj.filter.and];
}
const all_objs = [...obj, ...all_filters];
const uniqKeys = all_objs.reduce(
(acc, curr) => [...new Set([...acc, curr.field])],
[]
);
const updateItems = uniqKeys.map(obj => {
const filter_items = all_objs.filter(item => item.field === obj);
let resultObj = {};
if (filter_items && filter_items.length > 1) {
resultObj.or = [...filter_items];
} else if (filter_items && filter_items.length === 1) {
resultObj = { ...filter_items[0] };
}
return resultObj;
});
var result = { ...filterObj, filter: { and: [...updateItems] } };
console.log(result);
Try it.
I redid the implementation, it happened more universally.
Parses any filters according to your algorithm that it finds.
All test cases are worked.
Sandbox link: https://codesandbox.io/s/optimistic-mirzakhani-pogpw-so-i1u6h
let filterObj = {
feature: "test",
filter: {
and: [
{
field: "field1",
value: "2"
}
]
}
};
let obj = [
{
field: "field1",
value: "2"
},
{
field: "field1",
value: "1"
}
];
var FilterController = function(filter) {
var self = this;
self.filter = filter;
// encapsulated map of objects by fields
var storeMap = {};
// counter of objects
var counter = 0;
var tryPutObjectToMap = function(object) {
if (typeof object === "object") {
// get type for grouping
var objectType = self.getObjectGroupType(object);
if (objectType !== null) {
// cheack have group
if (!storeMap.hasOwnProperty(objectType)) {
storeMap[objectType] = [];
}
var duplicate = storeMap[objectType].find(function(sObject) {
return self.getObjectValue(sObject) === self.getObjectValue(object);
});
// check duplicate
if (duplicate === undefined) {
counter++;
storeMap[objectType].push(object);
} else {
// TODO: Handle duplicates
}
} else {
// TODO: handle incorrect object
}
}
};
// get filter structure from map
var getFilterStructureFromMap = function() {
var result = {};
// check exists root filter and filed if have objects
if (counter > 0) {
result["and"] = [];
}
for (var key in storeMap) {
if (storeMap.hasOwnProperty(key)) {
var array = storeMap[key];
if (array.length > 1) {
result["and"].push({
// clone array
or: array.slice()
});
} else {
result["and"].push(array[0]);
}
}
}
return result;
};
// rewrite and get current filter
// if you need^ create new object for result
self.rewriteAndGetFilter = function() {
self.filter.filter = getFilterStructureFromMap();
return self.filter;
};
// not prototype function for have access to storeMap
self.putObjects = function(objects) {
if (Array.isArray(objects)) {
// recursive push array elements
objects.forEach(element => self.putObjects(element));
// handle array
} else if (typeof objects === "object") {
// handle object
if (objects.hasOwnProperty("and") || objects.hasOwnProperty("or")) {
for (var key in objects) {
//no matter `or` or `and` the same grouping by field
// inner object field
if (objects.hasOwnProperty(key)) {
self.putObjects(objects[key]);
}
}
} else {
// filters props not found, try push to store map
tryPutObjectToMap(objects);
}
} else {
// TODO: Handle errors
}
};
if (self.filter.hasOwnProperty("filter")) {
// put and parse current objects from filter
self.putObjects(self.filter.filter);
}
};
// function for grouping objects.
// for you get filed name from object.
// change if need other ways to compare objects.
FilterController.prototype.getObjectGroupType = function(obj) {
if (typeof obj === "object" && obj.hasOwnProperty("field")) {
return obj.field;
}
return null;
};
// get object value
FilterController.prototype.getObjectValue = function(obj) {
if (typeof obj === "object" && obj.hasOwnProperty("value")) {
return obj.value;
}
return null;
};
var ctrl = new FilterController(filterObj);
ctrl.putObjects(obj);
var totalFilter = ctrl.rewriteAndGetFilter();
console.log(totalFilter);
console.log(JSON.stringify(totalFilter));
EDIT 1
I did not change the logic; I made a function based on it.
let filterObj = {
feature: "test",
filter: {
and: [
{
field: "field1",
value: "2"
}
]
}
};
let obj = [
{
field: "field1",
value: 2
},
{
field: "field1",
value: "1"
}
];
function appendToFilter(filter, inputObjects) {
var storeMap = {};
var counter = 0;
var handlingQueue = [];
// if filter isset the appen to handling queue
if (filter.hasOwnProperty("filter")) {
handlingQueue.push(filter.filter);
}
// append other object to queue
handlingQueue.push(inputObjects);
// get first and remove from queue
var currentObject = handlingQueue.shift();
while (currentObject !== undefined) {
if (Array.isArray(currentObject)) {
currentObject.forEach(element => handlingQueue.push(element));
} else if (typeof currentObject === "object") {
if (currentObject.hasOwnProperty("and") || currentObject.hasOwnProperty("or")) {
for (var key in currentObject) {
if (currentObject.hasOwnProperty(key)) {
handlingQueue.push(currentObject[key]);
}
}
} else {
// TODO: append fild exists check
if (currentObject.field) {
if (!storeMap.hasOwnProperty(currentObject.field)) {
storeMap[currentObject.field] = [];
}
var localValue = currentObject.value;
// check duplicate
if (storeMap[currentObject.field].find(object => object.value === localValue) === undefined) {
counter++;
storeMap[currentObject.field].push(currentObject);
}
}
}
}
currentObject = handlingQueue.shift();
}
// create new filter settings
var newFilter = {};
// check exists root filter and filed if have objects
if (counter > 0) { newFilter["and"] = []; }
for (var storeKey in storeMap) {
if (storeMap.hasOwnProperty(storeKey)) {
var array = storeMap[storeKey];
if (array.length > 1) {
newFilter["and"].push({
// clone array
or: array.slice()
});
} else {
newFilter["and"].push(array[0]);
}
}
}
filter.filter = newFilter;
}
// update filterObj
appendToFilter(filterObj, obj);
console.log(filterObj);
EDIT 2,3 (UPDATED)
With others objects support.
export function appendToFilter(filter, inputObjects) {
var storeMap = {};
var others = [];
var counter = 0;
var handlingQueue = [];
// if filter isset the appen to handling queue
if (filter.hasOwnProperty("filter") && filter.filter.hasOwnProperty("and")) {
handlingQueue.push(filter.filter.and);
}
// append other object to queue
handlingQueue.push(inputObjects);
// get first and remove from queue
var currentObject = handlingQueue.shift();
while (currentObject !== undefined) {
if (Array.isArray(currentObject)) {
currentObject.forEach(element => handlingQueue.push(element));
} else if (typeof currentObject === "object") {
if (
currentObject.hasOwnProperty("and") ||
currentObject.hasOwnProperty("or")
) {
for (var key in currentObject) {
if (currentObject.hasOwnProperty(key)) {
handlingQueue.push(currentObject[key]);
}
}
} else {
// TODO: append fild exists check
if (currentObject.field) {
if (!storeMap.hasOwnProperty(currentObject.field)) {
storeMap[currentObject.field] = [];
}
var localValue = currentObject.value;
// check duplicate
if (
storeMap[currentObject.field].find(
object => object.value === localValue
) === undefined
) {
counter++;
storeMap[currentObject.field].push(currentObject);
}
} else {
// handle others objects^ without field "field"
counter++;
others.push(currentObject);
}
}
}
currentObject = handlingQueue.shift();
}
// create new filter settings
var newFilter = {};
// check exists root filter and filed if have objects
if (counter > 0) {
newFilter["and"] = [];
}
for (var storeKey in storeMap) {
if (storeMap.hasOwnProperty(storeKey)) {
var array = storeMap[storeKey];
if (array.length > 1) {
newFilter["and"].push({
// clone array
or: array.slice()
});
} else {
newFilter["and"].push(array[0]);
}
}
}
// Append others to result filter
others.forEach(other => newFilter["and"].push(other));
filter.filter = newFilter;
}

JSON array filter does not apply

I am trying to filter the data from an array, but it is throwing an error saying
filter() is not function
Here is the code:
var selectedObject = [];
selectedObject= JSON.stringify(formsDataSource.data());
//console.log(selectedObject);
//var filtered = $.grep(selectedObject, function (el) {
// return el.po_order_no = 18;
//});
//console.log((filtered));
if (selectedObject == undefined) {
alert("Undefined");
} else {
var data= selectedObject.filter(function (element) { return element.po_order_no = "18"; })
alert("" + data);
}
I tried many things but it is still throwing an error. Any help?
Few observations :
selectedObject= JSON.stringify(formsDataSource.data());
This statement states that selectedObject is a string. A string does not have a filter() method.
condition inside filter function should be element.po_order_no == "18" instead of element.po_order_no = "18"
Solution :
var selectedObject = [
{
"po_order_no": 18,
"po_order_name": "abc"
},
{
"po_order_no": 19,
"po_order_name": "xyz"
}
];
if (selectedObject == undefined) {
console.log("Undefined");
} else {
var data = selectedObject.filter(element => element.po_order_no == "18")
console.log(data);
}

Unable to display array content

var dataHolder = [
{
"letterA" : "Fruits",
"letterB" : "Veges",
"letterC" : "Meat"
}
];
console.log(dataHolder[0].letterA);
var result = "";
function getData(myLetter) {
for (var i = 0; i < dataHolder.length; i++) {
if(dataHolder[i][myLetter] === myLetter){
console.log(dataHolder[i][myLetter]);
}
else{
console.log("No data found");
}
}
}
getData("letterA");
This is my code and i'm just trying to match the content of the array with the passed parameter, but every time it's giving No data found as output and not the matching content, it seems i'm missing something very basic here.
Any help would be highly appreciated.Thanks!!
You matching was wrong.
you are matching the letters == fruites .You should check is the key exist or not ,that's enough using hasOwnProperty()
Check this below. i was mention the error
var dataHolder = [{
"letterA": "Fruits",
"letterB": "Veges",
"letterC": "Meat"
}];
var result = "";
function getData(myLetter) {
for (var i = 0; i < dataHolder.length; i++) {
console.log('this is the pblm '+dataHolder[i][myLetter] +' != '+myLetter)
if (dataHolder[i].hasOwnProperty(myLetter)) {
console.log(dataHolder[i][myLetter]);
} else {
console.log("No data found");
}
}
}
getData("letterA");
For your way use with for...in
var dataHolder = [{
"letterA": "Fruits",
"letterB": "Veges",
"letterC": "Meat"
}];
var result = "";
function getData(myLetter) {
for (var i in dataHolder) {
if (dataHolder[i].hasOwnProperty(myLetter)) {
console.log(dataHolder[i][myLetter]);
} else {
console.log("No data found");
}
}
}
getData("letterA")
You are comparing value with key that is wrong.
The hasOwnProperty() method returns a boolean indicating whether the
object has the specified property as own (not inherited) property.
Use hasOwnProperty to check key exists or not.
dataHolder[i].hasOwnProperty(myLetter)
var dataHolder = [
{
"letterA" : "Fruits",
"letterB" : "Veges",
"letterC" : "Meat"
}
];
var result = "";
function getData(myLetter) {
for (var i = 0; i < dataHolder.length; i++) {
if(dataHolder[i].hasOwnProperty(myLetter)){
console.log(dataHolder[i][myLetter]);
}
else{
console.log("No data found");
}
}
}
getData("letterA");

Categories