Modify object value in array inside map - javascript

Trying to modify object value in array on condition on some arrays the override does not work, here is my snippet
const removeAction = (target, array, name) => {
let mutation = JSON.parse(JSON.stringify(array));
mutation.map( obj => {
if(obj.value === target.value) {
console.log(obj)
obj.checked = false
}
return obj
})
console.log(mutation)
removeCallback(mutation, name)
}
and I get back the original object in array. How do I debug this issue?

const modifiedArray = JSON.parse(JSON.stringify(array)).map(...

Map always returns new instance of array. So either assign that mutated map to some variable or loop over and mutate the original array.

You could take the mapped objects with destructuring the object and an updated property.
const
removeAction = (target, array, name) => {
removeCallback(array.map(obj => ({
...obj,
checked: obj.value === target.value ? false : obj.checked
})), name)
};

Related

Check if any property of object has null value

I have following array of objects data, that has multiple properties, some of them can have null value.
I want to filter through this array of objects and remove every object that has property of null value.
So far I have tried this code, but with no luck:
const noNull = data.filter((doc) => { return Object.values(doc).some(prop => { if (prop !== null) return doc; } )});
Any ideas how can I achieve this?
Thank you in advance.
Here Updated to keep items which do not have a null value
const noNull = obj.filter((doc) => { return Object.values(doc).every(prop => prop !== null)})
.some() and .every() expect boolean return value
reference

Assign object values conditionally JavaScript

I am receiving a data object from an api where some of its properties may have a value of null. I want to create a function that returns the object but for the properties that have a null value there is a "-" instead. I have tried:
const hyphenOrContent = movie => {
return Object.values(movie).map(val => {
return val === null ? "-" : val
});
}
but this only returns an array of the values. I've read that it's better not to use a for in loop so I would like to avoid using one if possible. Any help appreciated!
Map the object's entries, turning nulls into -s, then use Object.fromEntries to turn the array of entries into an object:
const hyphenOrContent = movie => Object.fromEntries(
Object.entries(movie).map(
([key, val]) => ([key, val === null ? "-" : val])
)
);
Just loop over the Object and alter the properties.
const hyphenOrContent = movie => {
Object.entries(movie).forEach(([key, val]) => {
if (val === null) movie[key] = '-';
});
};
var a = {
foo: null,
bar: '123',
baz: null
}
hyphenOrContent(a);
console.log(a);
If you do not want to alter the original, you can clone it.

Merging Objects Using Vanilla JavaScript

I've been working on an event handler to sync inputs with the state and came up with this solution:
https://gist.github.com/jadeallencook/678869f988bd65378d819496c4343e78
The handler pushes the value to the end point using the string and merges the result with the current state but I have to use lodash to accomplish it, is there anyway to do it in vanilla?
A reduce will produce a generic solution:
const path = 'foo-bar-num';
const paths = path.split('-');
const object = {};
const value = 'Woo hoo!';
paths.reduce(([object, value], path, idx) => {
object[path] = idx === paths.length - 1 ? value : {};
return [object[path], value];
}, [object, value]);
console.log(object)
Alternatively you can try lodash set function to set value for deeply nested object.
import set from 'lodash/set'
let path = 'foo-num';
const paths = path.split('-').join('.')
const value = 'some value';
set(object, paths, value)
You could store the last key and reduce only the keys before. Ath the end store the previous value and assign the new value.
function setValue(object, keys, value) {
var last = keys.pop(),
temp = keys.reduce((o, k) => o[k] = o[k] || {}, object);
temp.original = !(last in temp) ? null : temp[last];
temp[last] = value;
}
const
object = {},
path = 'foo-bar-num',
value = 'Woo hoo!';
setValue(object, path.split('-'), value);
console.log(object);

Optimization of double for with .map / .filter / .reduce or something

Is there a way to optimize the following with ES5 / ES6?
var obj = [];
var set;
for (var key_s in data1) {
set = false;
for (var key_s2 in data2) {
if (data1[key_s].id === data2[key_s2].id) {
obj.push({'id': data1[key_s].id,
'key': data1[key_s].key,
'value': data2[key_s2].value})
set = true;
break;
}
}
if (!set)
obj.push({'id': data1[key_s].id,
'key': data1[key_s].key,
'value': "EMPTY"})
}
I want to have an object which contains all keys of data1 and if a pair got the same id like the one in data2, it should take its value, otherwise it should become 'EMPTY'. Or maybe is there a way to use Object.assign with some special parameters or something?
You could use Map for data2 and use Array#map with data1 and the possible value of data2.
var map = new Map(data2.map(o => ([o.id, o]))),
obj = data1.map(({ id, key }) => ({ id, key, value: map.has(id)
? map.get(id).value
: 'EMPTY'
}));
This is pretty es6'ed. map over data1, the .find will return the matching object if one exists or else return undefined. set key_s.value to either the key_s2 value or "EMPTY" and then return the key_s object. You will end up with an array of objects. This assumes that data1 and data2 are arrays of objects, that is how your example was written so I figured it was the case.
let obj = data1.map(key_s => {
let newValue = data2.find(key_s2 => key_s.id === key_s2.id)
key_s.value = newValue ? newValue.value : "EMPTY"
return key_s
})
})
You could do it with Array#map, Array#find and Object.assign. By specifying the value in the first parameter of Object.assign, you can set a default to be overridden by the object from data2.
var obj = data1.map(obj1 => {
const obj2 = data2.find(obj2 => obj1.id === obj2.id);
return Object.assign({ value: 'EMPTY' }, obj1, obj2);
});
Using spread properties, that Object.assign could be changed to:
{ value: 'EMPTY', ...obj1, ...obj2 }

Converting an array of objects in to a single object

Have an array which contains a no of json .
[{linkValue:"value1"},{linkValue:"value2"},{linkValue:"value3"},{linkValue:"value4"},{linkValue:"value5"}]
Note that each Json have same key . I want to convert this array into a single json like
{linkValue1:"value1",linkValue2:"value2",linkValue3:"value3",linkValue4:"value4",linkValue5:"value5"}
one thing i also need to know . my array is also inside a json how i get this arry from that json ?
My initial json is
{name:"value",age:"value",linkValue:[[{linkValue:"value1"},{linkValue:"value2"},{linkValue:"value3"},{linkValue:"value4"},{linkValue:"value5"}]
]}
I'm expcting my final json look like :
{name:"value",age:"value",linkValue1:"value1",linkValue2:"value2",linkValue3:"value3",linkValue4:"value4",linkValue5:"value5"}
can anyone please help me
Use Array.forEach and add properties to an empty object:
let source = {name:"value",age:"value",linkValue:[[{linkValue:"value1"},{linkValue:"value2"},{linkValue:"value3"},{linkValue:"value4"},{linkValue:"value5"}]]};
// Copy the array in a variable
let yourArray = source.linkValue[0];
// Delete the original array in the source object
delete source.linkValue;
yourArray.forEach((item, index) => {
source["linkValue" + (index + 1)] = item.linkValue
});
console.log(source); // Should have what you want
Using reduce API,
let targetObj = srcArr.reduce((accumulator, value, index)=>{
accumulator['linkValue'+(index+1)] = value.linkValue;
return accumulator;
}, {});
[{linkValue:"value1"},{linkValue:"value2"},{linkValue:"value3"},{linkValue:"value4"},{linkValue:"value5"}]
This is javascript Array contains multiple javascript object.
{linkValue1:"value1",linkValue2:"value2",linkValue3:"value3",linkValue4:"value4",linkValue5:"value5"}
If you need structure like this,Then define a single javascript object and add linkvalue1,linkvalue2 etc. as a member of that object and then add it to javascript Array.
Give this a try.
myObj.linkValue = myObj.linkValue.map((obj, index) => ({ [`linkValue${index + 1}`]: obj.linkValue }))
Solution with reduce
// HELPER FUNCTIONS
// pick properties from object with default value
function pick (props, sourceObj, defaultValue) {
return props.reduce(
(obj, prop) =>
Object.assign(obj, { [prop]: sourceObj[prop] || defaultValue }),
{}
)
}
// get property value or default
function propOr (propName, obj, defaultValue) {
return obj[propName] || defaultValue
}
// flatten nested array
function flattern (nestedArray) {
return nestedArray.reduce((flat, innerArray) => flat.concat(innerArray), [])
}
// LINKS BUILDER based on REDUCE
function buildLinks (linksArray) {
return linksArray.reduce((accumulator, item, index) => {
accumulator['linkValue' + (index + 1)] = item.linkValue
return accumulator
}, {})
}
// TRANSFORMATION FUNCTION - takes json and produce required output
function transform(json) {
return Object.assign(
{},
pick(['name', 'age'], json, null),
buildLinks(flattern(propOr('linkValue', json, [])))
)
}
// EXECUTION
const result = transform(source)
PS> You can use libraries like Lodash or Ramda and replace helper functions defined by me with ones from library

Categories

Resources