Assign, and set js object property conditionally [duplicate] - javascript

This question already has answers here:
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Conditionally set an object property
(7 answers)
How to conditionally add properties to a javascript object literal
(8 answers)
Closed 8 months ago.
Here's my code:
app.post('/ujfeladat', (req, res) => {
const {nev, tipus, szid} = req.body;
const hianyos = () => {
if(tipus === 'hianyos'){
return {rang: -1}
}
return
}
db('fl').insert({
nev: nev,
tipus: tipus,
szid: szid,
hianyos() //returns an error
}).returning('*')
.then(data => res.json(data))
.catch(err => console.log(err))
})
How can i do that to add the rang property to the object only if the tipus === 'hianyos'?

Updated answer:
Here's how you can do it:
// Will result in { foo: 'foo', bar: 'bar'}
const item = {
foo: 'foo',
... true && { bar: 'bar' },
... false && { falsy: 'falsy' },
}
console.log(item)
Explanations:
Short-circuit evaluation (true && {}, false && {}) would return an Object or a Boolean false value.
In the case an Object is returned, its properties get spread and assigned to the parent object.
In the case false value is returned, the parent object isn't polluted, because ES6 treats false, undefined, null and etc values as {}. Therefore spreading ...{} won't assign any properties to the parent object. More details about this, you can find here.
Original answer:
Here's how you can do it:
db('fl').insert({
nev: nev,
tipus: tipus,
szid: szid,
...tipus === 'hianyos' ? { rang: -1 } : {}
})
Explanations:
As you can see the ternary operator always returns an object.
If the condition is true, then it returns { rang: -1 }, otherwise an empty object {}.
After that we spread out ... the resulted object (from the ternary operation) and the object's properties are assigned to the parent object.
If there aren't any properties, then nothing will be assigned, which is our goal.
Code example: (sometimes few lines of code better than a thousands of words)
// Will result in { foo: 'foo', bar: 'bar'}
const item = {
foo: 'foo',
... true ? { bar: 'bar' } : {},
... false ? { falsy: 'falsy' } : {},
}
console.log(item)
In other answer I explained the same idea, but for arrays. You can check it too here.

Related

Is there a better/shorter way to check a value of an object within an array which is part of an object in Javascript?

I'm sure this question must have been answered before, so a link (or what specifically to ask Google) would suffice, but what is the best way to do a check in a scenario like this (and does the new ? operator help in scenarios like this):
/**
* An API returns a job object like:
* { id: 123, name: 'The Job', details: [ { detail_name: "Foo", some: "thing" }, { detail_name: "Bar", some: "thing else" } ] }
*/
const fooDetail = job.details.find(attr => {
return attr.detail_name === 'Foo' });
if (fooDetail && fooDetail.detail_name === "Foo") {
// todo process `some: "thing"`
}
It seems long winded to have to find an object in an array based on a property, but then having to check again that the object exists before checking the property (or get a can't get detail_name of undefined error). Is there a better/shorter way?
You can use Array.some
This will return true if one is found..
The same callback as find can be used
const hasDetail = job.details.some(attr => {
return attr.detail_name === 'Foo' });
if (hasDetail) {
// todo process `some: "thing"`
}
If you're simply want to get the value and then later on check if the property exists, you can use find and ?. operator
const addDetail = job.details.find(attr => {
return attr.detail_name === 'Foo' });
if (addDetail?.detail_name === 'Foo') {
// todo process `some: "thing"`
}
You can do also
job.details.forEach(x=>{
if(x.detail_name == "Foo") {
console.log(x.some);
}
});

JS - Destructuring by picking only what you need [duplicate]

This question already has answers here:
Is it possible to destructure onto an existing object? (Javascript ES6)
(16 answers)
ES2015 deconstructing into an object [duplicate]
(1 answer)
How to get a subset of a javascript object's properties
(36 answers)
Closed 4 years ago.
I'm trying to understand ES6, specifically destructuring feature.
How can I translate these lines using destructuring?
const user = {...}
const sessionData = ({
session_id: user.session_id,
selector: user.selector,
validator: user.validator
})
I tried
const sessionData = {session_id, selector, validator} = user
But it raises a syntax error, because of course destructuring is for giving a certain variable a value from an object but I don't understand how to do something like this with an object
Use
const { session_id, selector, validator } = user;
Then
const sessionData = { session_id, selector, validator };
You could also do it like so (using anonymous functions)
const user = { session_id: 1, selector: "my-selector", validator: 1, unused: 3 };
const session = (({ session_id, selector, validator }) => ({ session_id, selector, validator }))(user);
console.log(session);
You can use a function to create the new object with the fields you want.
const original = { a: 1, b: 2, c: 3 };
const pick = (o, fields) => fields.reduce((acc, key) => {
acc[key] = o[key];
return acc;
}, {});
console.log(pick(original, ['a', 'b']));
Or use the comma operator to destructure and assign.
const original = { a: 1, b: 2, c: 3 };
const newone = ({ a, b } = original, { a, b });
console.log(newone);
But keep in mind that the comma operator creates global variables, if the variables to assign the destructure are not declared. Hope this helps.

is there a way to filter array based on flag inside an array

I am trying to do filter an array based on flag isSome: true. I want to filter when that flag is not present in that array
var value = [
{ "somevalues": {},
"moreDetails": {
"isSome": "true"
}
},
{ "somevalues": {},
"moreDetails": {}
},
{ "somevalues": {},
"moreDetails": {}
},
]
const valuewithisSome = value.filter(o => o.moreDetails && o.moreDetails.isSome);
const valuewithoutisSome = value.filter(o => o.moreDetails && !o.moreDetails.isSome);
console.log(valuewithisSome);
console.log(valuewithoutisSome);
valuewithisSome is working as expected and returning array with isSome: true.
valuewithoutisSome is not working as expected as i don't want to pass isSome false in morevalues array, is there a way to filter without even passing that flag?
The "without" code you already have should work:
const valuewithoutisSome = value.filter(o => o.moreDetails && !o.moreDetails.isSome);
The expression o.moreDetails.isSome will evaluate to undefined if the "isSome" property is missing or explicitly false-y, so !o.moreDetails.isSome will be true in that case.
Now while that will work, if you want to explicitly test for the property being false only when it's actually present, you can do this:
const valuewithoutisSome = value.filter(o =>
o.moreDetails &&
(!("isSome" in o.moreDetails) || !o.moreDetails.isSome)
);
That will only return false (and filter out the array entry) when the "isSome" property is present. If it's not, or if it's present and true, then the entry will be in the filtered result.
Your isSome property type is string. Remove double quetos from true.
{ "somevalues": {},
"moreDetails": {
"isSome": true
}
},

JS Recursive object assign [duplicate]

This question already has answers here:
How to deep merge instead of shallow merge?
(47 answers)
Closed 4 years ago.
I learned that when using Object.assign() it extends only the top level object. How can I deeply extend the object? For example, let's say I have the following source object:
const source = {
id: 1,
otherKey: {},
params: {
page: {
a: 1,
b: {}
},
data: {
b: 1
}
}
}
And I am using Object.assign() like this:
Object.assign({}, source, {
params: {
page: {
a: 2
}
}
}
The result will be:
{
id: 1,
otherKey: {},
params: {
page: {
a: 2
}
}
}
How can I preserve the params.data key and the params.page.b key in a shallow clone way.
oldObject.params.data === newObject.params.data // true
oldObject.params.page === newObject.params.page // false
oldObject.params.page.b === newObject.params.page.b // true
Note: This question is not the same as How to deep merge instead of shallow merge. The answers there does not give the expected results.
Check this bin that takes an answer from the above link.
So in your posted code, what happens is, if the source and target both contain the same key then nothing happens. The object is recursed down to the children. However if you simply change the inner block to this:
if (!target[key]) {
Object.assign(target, { [key]: {} });
}else{
target[key] = Object.assign({}, target[key])
}
mergeDeep(target[key], source[key]);
This will create a new assigned object for any key that is found in both the source and the target. Interestingly though, if you do this, your expected falseys will not show up in the console. This is because the target will always match the result, as it is the final mutated object. So in order to get your expected false results, you need to do something like the following:
var tester = source.params
const result = mergeDeep(source, b)
console.log(tester === result.params) // this will be false after the above addition
You can see your desired result here: http://jsbin.com/vicemiqiqu/1/edit?js,console

Typescript - if conditrional inside a map

I am mapping a subset of user data to an object of a refined data set. Inside the map i want to check if a variable is null or undefined, and if yes, then to set this variable to a placeholder value.
The issue I am facing is that declaring an if statement inside the map is causing an error, but even though a map can have an index as a parameter, how can we use it functionally with a conditional Statement? Any insight most appreciated.
return this.UserService.search(url)
.map((data) => {
console.log(data);
data.result = <any> data.result.map((user, index) => ({
// if statement causing error here
if(user.name === null || user.name === undefined){
// error with this if condition
},
id: user.id,
name: user.name,
type: user.type,
password: user.password,
}));
return data;
}).map(data => ({
meta: { totalItems: data.size },
data: data.result,
}));
You're attempting to use an object literal as the return type, but naturally, an if statement (or any statement) can't be inside object literal syntax.
So instead, define a function body, which also uses curly braces, and put your code inside with an explicit return statement.
// Starts function body instead of single expression-v
data.result = <any> data.result.map((user, index) => {
if (some_condition) {
return "some value"; // The object?
} else {
return "other value"; // A different object?
}
/*
// I assume these are to be used in the object you return
id: user.id,
name: user.name,
type: user.type,
password: user.password,
*/
});
You can express conditions in literal maps, but it is somewhat ugly.
return {
a: 1,
...(some_condition && {
b: 1,
})
};
As far as i know you can't do that with JUST a map.
however you could follow it up with a filter() function:
const newArray = oldArray.map((value, index) => condition ? value : null).filter(v => v);
you basicaly iterate over each item and then return the value or null depending on your condition.
Now once you have the map you just filter it by removing the null values from the array.
Notice that the original array is not altered and a new one is returned.
thanks for the idea #user8897421 for the idea. i just wanted to turn it into a one liner.

Categories

Resources