JavaScript: destructuring with a conditional statement - javascript

I would like to get firstName and lastName properties from a whole user object. I need to use a conditional statement too.
How to do something like that?
getUserById(id)and getUserByAddress(id) use the JavaScript find() method that returns an element or undefined.
let { firstName, lastName } = getUserById(id);
if ({ firstName, lastName } === undefined) {
{ firstName, lastName } = getUserByAddress(id);
}
return `${firstName} ${lastName}`;

const { firstName, lastName } = getUserById(id) || getUserByAddress(id) || {};
if (firstName && lastName) {
return `${firstName} ${lastName}`;
}
return "Unknown user";
If getUserById(id) is falsy, getUserByAddress(id) will be executed. If this is falsy, too, {} will at least prevent throwing an error.

const episodeParser = (
query: string, codeType ?: string, productId?: number, newProductId?: number
) => {
let queryParams = {
query,
codeType,
processId : AppConfig.PROCESS_ID,
...(productId && {productId}),
...(newProductId && {newProductId})
};
return queryParams;
}
Here, productId and newProductId both are optional, whatever the value of id will be there, these key will be getting in queryParams.

Related

Check object variable exists when using object destructuring

I have a 'getData' function which gets passed a 'data' variable. Inside the function I'm trying to access an object 'data.someObject' which may or may not exist because it comes from an outside library.
What is the best approach to check if it does exist before trying to use it? Also see I'm using object destructuring here aswell.
const getData = (data) => {
const { name, age } = data.someObject; // someObject may or may not exist
console.log(name, age);
}
I thought doing this might work:
const { name, age } = data.someObject || {};
But I wasn't sure if that would throw an error.
Thanks
You can use || & if required provide default values while destructuring.
function print(user) {
const { fname = "Anonymous", lname = "Panda" } = user.fullname || {};
console.log(`Hello ${fname} ${lname}`);
}
print({ fullname: { fname: "John", lname: "Doe" } });
print({});
print({ fullname: null });
Personally I would put an if statement:
const getData = (data) => {
if (data.someObject == null) {
// Here you can return, throw an error or do anything else you might need
}
const { name, age } = data.someObject; // someObject may or may not exist
console.log(name, age);
}

onChange to check all property of object exist and is not undefined or empty string

This is a very common usage where you have to check whether all fields are filled. I use react onChange and apply e.target.name as key to my object.
like I do console.log(this.state.user); I will get
user : {
name:"something",
age:1
}
but how to check if everything is not empty or null? I check manually like user.name != undefined but my key is more than 10. Is there any better lodash method to do this?
I set state like this
const user = this.state.user;
user[field] = event.target.value;
this.setState({
user
});
You can iterate the values of your object and use reduce method.
const allExist = Object.values(this.state.user)
.reduce(function(accumulator, current){
return accumulator && !!current
}, true);
const user = {
name:"something",
age:1
}
const allExist = Object.keys(user)
.reduce(function(accumulator, current){
return accumulator && !!current
}, true);
console.log(allExist);
You could use Object.keys method - loop the resulting array and check that each key has a valid value:
const user = {
name: "Tom",
age: 28,
address: null,
occupation: "Programmer",
interest: "JavaScript",
dob: undefined
}
const keys = Object.keys(user);
for (let i = 0; i < keys.length; i++) {
if (user[keys[i]] == null) {
console.log(`${keys[i]} needs a value`);
}
}

JS finding the IndexOf() a substring within a string

I'm using React to build a restaurant violation app, and I'm trying to return results where the searched term is a substring of the data set. However, I'm getting an error message saying;
ViolationsRequest.jsx:49 Uncaught TypeError: Cannot read property 'indexOf' of null.
Based on my tests, it looks like door.restaurant is being console-logged as undefined. Strangely enough, this code works as an exact match, i.e., if you switch out the if block as:
if (this.props.restaurant == door.restaurant) {
This is my code block.
const violationElements = this.state.doors.map((door, idx) => {
if (door.restaurant.indexOf(this.props.restaurant) !== -1) {
console.log();
return (
<ViolationsView key={idx}
restaurant={door.restaurant}
building={door.building}
street={door.street}
zip={door.zip}
phone={door.phone}
cuisine={door.cuisine}
inspectionDate={door.inspectionDate}
action={door.action}
violationCode={door.violationCode}
violationDescription={door.violationDescription}
criticalFlag={door.criticalFlag}
score={door.score}
grade={door.grade}
gradeDate={door.gradeDate}
inspectionType={door.inspectionType}
/>
)
}
});
This is my state.doors array:
const cleanData = restaurantData.data.map((inspectionData) => {
const [sid, id, position, createdAt, createdMeta,
updatedAt, updatedMeta, meta, camis, dba, boro,
building, street, zipcode, phone, cuisine,
inspectionDate, action, violationCode,
violationDescription, criticalFlag, score, grade,
gradeDate, recordDate, inspectionType] = inspectionData;
return {
sid: sid,
restaurant: dba,
building: building,
street: street,
zip: zipcode,
phone: phone,
cuisine: cuisine,
inspectionDate: inspectionDate,
action: action,
violationCode: violationCode,
violationDescription: violationDescription,
criticalFlag: criticalFlag,
score: score,
grade: grade,
gradeDate: gradeDate,
inspectionType: inspectionType,
};
});
One of your doors.restaurant is null, which is what the error message states. Null, not undefined. If it was undefined the error message would have said so. When you call doors.restaurant.indexOf on this value it returns an error.
As I type this, you seem to have already figured it out.
I think the problem is you aren't using the === operator, so with the == you are validating only value not type.
Example:
var foo = null;
var bar = '';
var baz = 0;
var off = {};
console.log(bar == baz); // true
console.log(bar === baz); // false
console.log(foo == off.bar); // true
console.log(foo === off.bar); // false
so probably this.props.restaurant == door.restaurant is true
but this.props.restaurant === door.restaurant is false

Mongodb: dynamically exclude fields from update function [duplicate]

I would update a collection setting the value only if the new values are not null.
I have a code like this:
...
var userName = req.body.nome;
var userSurname = req.body.cognome;
var userAddress = req.body.indirizzo;
collection.update(
{_id:ObjectId(req.session.userID)},
{$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)
Is there an easy way for doing this?
ANOTHER WAY:
if I could take the value req.body.* from the placeholder of the form where I take the data, I could solve the problem.. but is this possible?
You could try something like this:
var objForUpdate = {};
if (req.body.nome) objForUpdate.nome = req.body.nome;
if (req.body.cognome) objForUpdate.cognome = req.body.cognome;
if (req.body.indirizzo) objForUpdate.indirizzo = req.body.indirizzo;
//before edit- There is no need for creating a new variable
//var setObj = { $set: objForUpdate }
objForUpdate = { $set: objForUpdate }
collection.update({_id:ObjectId(req.session.userID)}, objForUpdate )
You can use lodash like this other question: https://stackoverflow.com/a/33432857/4777292
_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
would be
{b:1}
Are you not just asking to pass in all the fields that you posted? Why not do this then?
(And basically just a cut and paste of your code):
collection.update(
{_id: ObjectId(req.session.userID)},
{$set: req.body }
)
Then whatever content you posted as fields is set within your update.
Note that use of set will only overwrite, or add new fields. If you just want to replace the whole document, then remove the whole {$set: (..) } notation and just pass in req body as it's a valild object.
You can use mongoose for that by casting req.body to your model,
I assume you have mongoose model called User, and in your controller,
var userModel = new User(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true}, function(err){
console.log("Error occured!");
});
There is no mongoose tag, but I strongly recomment to use that. For more details;
Mongoose Update
Mongoose Model
If there is not any field that you dont want users to be able to change. since this method will take any value which is not empty and update it. you can do it like this.
const updatedFields = {};
Object.keys(req.body).forEach(key => {
if (!isEmpty(req.body[key])) {
updatedFields[key] = req.body[key];
}
});
YourModel.findOneAndUpdate(
{ employee_id: req.body.employee_id },
{$set:updatedFields},
{new:true}).then(updatedObj =>{
console.log("updated obj:",updatedObj);
})
is empty function
const isEmpty = value =>
value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
This version still allows for null string fields to be respected and updated. Omitted fields would be ignored.
const cleanedObject = Object.keys(origObject).reduce((acc, k) => {
if (typeof origObject[k] === "undefined") return acc;
acc[k] = origObject[k];
return acc;
}, {});
collection.update({_id:ObjectId(req.session.userID)}, cleanedObject })
Probably you've got already user authenticated so you should have req.user.*
in this case you can use ternary operator to assign the value and update it with either new one or the current one (so there is no update)
var userName = req.body.nome ? req.body.nome : req.user.nome;
var userSurname = req.body.cognome ? req.body.nome : req.user.cognome;
var userAddress = req.body.indirizzo ? req.body.indirizzo : req.user.indirizzo;
collection.update(
{_id:ObjectID(req.session.userID)},
{$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)
If you don't have req.user then you can do it in 3 steps.
1. find user in collection
2. get current data
3. update data with new or current (as above)
let currentName
let currentSurname
db. collection.findOne({_id: ObjectID(req.session.userID)}, (err, user) => {
if (err) { } // handle error here
else if (user) {
currentName = user.name
currentSurname = user.surname
}
})
let objForUpdate = {}
for (const key of Object.keys(req.body)) {
if (req.body[key]) objForUpdate = Object.assign({}, objForUpdate, { [key]: req.body[key] })
}
collection.update({_id:ObjectId(req.session.userID)}, { $set: objForUpdate })
This will dynamically add fields in objForUpdate if defined in the body.
var userName = req.body.nome;
var userSurname = req.body.cognome;
var userAddress = req.body.indirizzo;
collection.update(
{ _id: ObjectId(req.session.userID) },
{
$set: {
...userName && { nome: userName },
...userSurname && { cognome: userSurname },
...userAddress && { indirizzo: userAddress },
},
}
)
The answer by Hüseyin BABAL is on the right track, but that will generate a warning from mongo because calling new User() will create a new _id which is immutable. What you want to do is the following:
const userModel = Object.assign(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true},
function(err){
console.log("Error occured!");
});

MongoDB, update collection field if new value is not null

I would update a collection setting the value only if the new values are not null.
I have a code like this:
...
var userName = req.body.nome;
var userSurname = req.body.cognome;
var userAddress = req.body.indirizzo;
collection.update(
{_id:ObjectId(req.session.userID)},
{$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)
Is there an easy way for doing this?
ANOTHER WAY:
if I could take the value req.body.* from the placeholder of the form where I take the data, I could solve the problem.. but is this possible?
You could try something like this:
var objForUpdate = {};
if (req.body.nome) objForUpdate.nome = req.body.nome;
if (req.body.cognome) objForUpdate.cognome = req.body.cognome;
if (req.body.indirizzo) objForUpdate.indirizzo = req.body.indirizzo;
//before edit- There is no need for creating a new variable
//var setObj = { $set: objForUpdate }
objForUpdate = { $set: objForUpdate }
collection.update({_id:ObjectId(req.session.userID)}, objForUpdate )
You can use lodash like this other question: https://stackoverflow.com/a/33432857/4777292
_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
would be
{b:1}
Are you not just asking to pass in all the fields that you posted? Why not do this then?
(And basically just a cut and paste of your code):
collection.update(
{_id: ObjectId(req.session.userID)},
{$set: req.body }
)
Then whatever content you posted as fields is set within your update.
Note that use of set will only overwrite, or add new fields. If you just want to replace the whole document, then remove the whole {$set: (..) } notation and just pass in req body as it's a valild object.
You can use mongoose for that by casting req.body to your model,
I assume you have mongoose model called User, and in your controller,
var userModel = new User(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true}, function(err){
console.log("Error occured!");
});
There is no mongoose tag, but I strongly recomment to use that. For more details;
Mongoose Update
Mongoose Model
If there is not any field that you dont want users to be able to change. since this method will take any value which is not empty and update it. you can do it like this.
const updatedFields = {};
Object.keys(req.body).forEach(key => {
if (!isEmpty(req.body[key])) {
updatedFields[key] = req.body[key];
}
});
YourModel.findOneAndUpdate(
{ employee_id: req.body.employee_id },
{$set:updatedFields},
{new:true}).then(updatedObj =>{
console.log("updated obj:",updatedObj);
})
is empty function
const isEmpty = value =>
value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
This version still allows for null string fields to be respected and updated. Omitted fields would be ignored.
const cleanedObject = Object.keys(origObject).reduce((acc, k) => {
if (typeof origObject[k] === "undefined") return acc;
acc[k] = origObject[k];
return acc;
}, {});
collection.update({_id:ObjectId(req.session.userID)}, cleanedObject })
Probably you've got already user authenticated so you should have req.user.*
in this case you can use ternary operator to assign the value and update it with either new one or the current one (so there is no update)
var userName = req.body.nome ? req.body.nome : req.user.nome;
var userSurname = req.body.cognome ? req.body.nome : req.user.cognome;
var userAddress = req.body.indirizzo ? req.body.indirizzo : req.user.indirizzo;
collection.update(
{_id:ObjectID(req.session.userID)},
{$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)
If you don't have req.user then you can do it in 3 steps.
1. find user in collection
2. get current data
3. update data with new or current (as above)
let currentName
let currentSurname
db. collection.findOne({_id: ObjectID(req.session.userID)}, (err, user) => {
if (err) { } // handle error here
else if (user) {
currentName = user.name
currentSurname = user.surname
}
})
let objForUpdate = {}
for (const key of Object.keys(req.body)) {
if (req.body[key]) objForUpdate = Object.assign({}, objForUpdate, { [key]: req.body[key] })
}
collection.update({_id:ObjectId(req.session.userID)}, { $set: objForUpdate })
This will dynamically add fields in objForUpdate if defined in the body.
var userName = req.body.nome;
var userSurname = req.body.cognome;
var userAddress = req.body.indirizzo;
collection.update(
{ _id: ObjectId(req.session.userID) },
{
$set: {
...userName && { nome: userName },
...userSurname && { cognome: userSurname },
...userAddress && { indirizzo: userAddress },
},
}
)
The answer by Hüseyin BABAL is on the right track, but that will generate a warning from mongo because calling new User() will create a new _id which is immutable. What you want to do is the following:
const userModel = Object.assign(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true},
function(err){
console.log("Error occured!");
});

Categories