If statement syntax error in JS - javascript

I am trying to use an if/else and I can't figure out where I'm going wrong with the syntax. I want the payload to only submit school_ids if the role isn't p_admin. Thank you for your help!
const createUser = (payload) => request.postJSON(
'/register',
excludeObjNullValue({
username: payload.username,
email: payload.email,
password: payload.password,
first_name: payload.firstName,
last_name: payload.lastName,
role: payload.role,
district_id: payload.districtId,
if (role !== 'p_admin'){
school_ids: payload.schoolIds
}
})
);

I see 2-3 options depending on your excludeObjNullValue function:
You can either break that expression up in to a couple of statements, or
Or use property spread notation and the conditional operator, or
If excludeObjNullValue does what the name suggests, you can use a conditional without spread notation and rely on excludeObjNullValue to exclude it
Option 3 may well be your best bet, but I'll give them in order:
Option 1: The multi-statement way:
const createUser = (payload) => {
const options = {
username: payload.username,
email: payload.email,
password: payload.password,
first_name: payload.firstName,
last_name: payload.lastName,
role: payload.role,
district_id: payload.districtId,
};
if (role !== 'p_admin') {
options.school_ids = payload.schoolIds;
}
return request.postJSON('/register', excludeObjNullValue(options));
};
Option 2: Property spread and the conditional operator
Property spread is a Stage 3 proposal but support for it is already shipping in Chrome and Firefox, and if you're transpiling you can tell your transpiler to support it. That would look like this:
const createUser = (payload) => request.postJSON(
'/register',
excludeObjNullValue({
username: payload.username,
email: payload.email,
password: payload.password,
first_name: payload.firstName,
last_name: payload.lastName,
role: payload.role,
district_id: payload.districtId,
{...(role !== 'p_admin' ? {school_ids: payload.schoolIds} : {}}
}
})
);
Whether it's a good idea even if supported is your call. :-) It does briefly create an extra object and iterator.
Option 3: Rely on excludeObjNullValue to exclude properties with null values:
If it really does what the name suggests, then it will remove school_ids if we give the value null to it. So:
const createUser = (payload) => request.postJSON(
'/register',
excludeObjNullValue({
username: payload.username,
email: payload.email,
password: payload.password,
first_name: payload.firstName,
last_name: payload.lastName,
role: payload.role,
district_id: payload.districtId,
school_ids: role !== 'p_admin' ? payload.schoolIds : null
}
})
);

You can't write if statement at the object declaration. Also you need to explicitly defined body for your arrow function. So you can do something like
const createUser = (payload) => {
const obj = {
username: payload.username,
email: payload.email,
password: payload.password,
first_name: payload.firstName,
last_name: payload.lastName,
role: payload.role,
district_id: payload.districtId
};
if(obj.role !== 'p_admin') {
obj.school_ids = payload.schoolIds
}
return request.postJSON('/register', excludeObjNullValue(obj));
}

Related

JavaScript object shorthands

I have this clunky code here and hope there is any way to shorten this.
By the way, "req.query" is my query object from an nodejs express server.
const q = req.query
User.insertOne({
firstName: q.firstName,
lastName: q.lastName,
bestFriend: q.bestFriend,
hobbies: q.hobbies,
address: {
street: q.address.street,
number: q.address.number,
plz: q.address.plz,
city: q.address.city,
country: q.address.country,
},
contact: {
telephone: q.contact.telephone,
email: q.contact.email,
},
})
My first solution was - as you can see - to replace req.query with q, but this does not seem to be enough.
Maybe you could do this with the "with" statement, but i haven't used it before and I've heard that you shouldn't implement it (don't know why....).
By reading your title I understood you want to use ES6 object property shorthand. To achieve that in your current setup you would also need to use object destructuring, here's the code:
//Object destructuring:
const { firstName, lastName, bestFriend, hobbies } = req.query;
const { street, number, plz, city, country } = req.query.address;
const { telephone, email } = req.query.contact;
//Using the ES6 object property shorthand:
User.insertOne({
firstName,
lastName,
bestFriend,
hobbies,
address: {
street,
number,
plz,
city,
country,
},
contact: {
telephone,
email,
},
})
As long as the property names matches with each other, you can directly assign them in javascript and the relevant properties will be mapped.
const q = req.query
User.insertOne(q);
If the properties don't match, use spread operator ( ... ) from ES6 which comes handy while mapping objects.
You can use the lodash library and use a the pick method.You only need to specify the names of the fields that you want from req.query,and it'll return an object containing those values which you can use.
const _ = require("lodash");
User.insertOne(_.pick(req.query, [
"firstName",
"lastName",
"bestFriend",
"hobbies",
"address.street",
"address.number",
"address.plz",
"address.city",
"address.country",
"contact.telephone",
"contact.email"
]))
In case the OP's task was about passing just a subset of the queried data into the method (but actually not just for that) then the OP might have a look into the destructuring assignment syntax, into the spread syntax as well as into the rest parameters syntax.
const req = {
query: {
foo: 'Foo',
bar: 'Bar',
firstName: 'Anni',
lastName: 'Smith',
bestFriend: 'Jane Doe',
hobbies: '',
address: {
street: 'Any Lane',
number: 42,
plz: '1-234-456',
city: 'Some City',
country: 'Motherland',
},
contact: {
telephone: '9-87-654-321',
email: 'anni.smith#provider.com',
},
more_not_needed_data: {
baz: 'Baz',
biz: 'Biz',
},
},
};
const userDataFromRest =
(({ foo, bar, more_not_needed_data, ...data }) => data)(req.query);
const explicitUserData = (
({
firstName, lastName, bestFriend, hobbies, address, contact,
}) => ({
firstName, lastName, bestFriend, hobbies, address, contact,
})
)(req.query);
/*
User
.insertOne((({ foo, bar, 'more not needed data', ...data }) => data)(req.query));
User
.insertOne((
({
firstName, lastName, bestFriend, hobbies, address, contact,
}) => ({
firstName, lastName, bestFriend, hobbies, address, contact,
})
)(req.query));
*/
console.log({
query: req.query,
userDataFromRest,
explicitUserData,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

Is mongoose findOne guaranteed to return the latest inserted doc it finds?

I have the following in the database:
username: Murat1010
firstName: Murat
lastName: Paşa
city: İstanbul
createdAt: 2022-07-15T23:24:32.382+00:00
username: Ömer98
firstName: Ömer
lastName: Demir
city: İstanbul
createdAt: 2022-07-15T23:25:00.023+00:00
username: Yaser334
firstName: Yasser
lastName: Tayyar
city: İstanbul
createdAt: 2022-07-15T23:27:59.688+00:00
I have the following Mongoose code:
const newestMember = await Users.findOne({city: "İstanbul"})
Is newestMember guaranteed to return Murat's Doc? guaranteed to return the newest one?
can I stick to findOne?
If it's not correct, then how?
No it's not guaranteed.
Read here
I would do:
const newestMember = await Users.findOne({city: "İstanbul"}).sort({createdAt: -1})

I need to unstructure an object to update the variables defined in data

it's my first post. I need to destructure to update a variable defined in "data", I have the following code snippets. I'm using VUE.
data: () => ({
id: '',
phone: '',
email: ''
}),
methods: {
async getId(){
{this.id, this.email, this.phone} = this.$route.query.item
}
}
Actually you can assign to existing variables.
The syntax is just a little weird.
This should work
({id: this.id, phone: this.phone, email: this.email} = this.$route.query.item)
Here's a working example
You can't destructure to existing props but to new ones only:
data () {
return {
item: {
id: '',
phone: '',
email: ''
}
}
},
...
methods: {
async getId(){
{ id, email, phone } = this.$route.query.item
Object.assign(this.item, { id, email, phone })

Is there a better way to use applySpec here

I think the redundancy here can be removed by using some function insde ramda but I am very new to this library so i cant think of how.Some help would be really appreciated
let lib = {
getFormattedPropsForUser: R.compose(
R.pickBy(R.identity),
R.applySpec({
username: R.prop('username'),
password: R.prop('password')
})),
getFormattedQueryParamsForUser: R.compose(
R.pickBy(R.identity),
R.applySpec({
_id: R.prop('_id'),
username: R.prop('username'),
password: R.prop('password')
})
)
};
Extract the common part of both applications to a function, and add the ability to add more items to the spec using partial application and object spread.
Example:
const forUser = spec => R.compose(
R.pickBy(R.identity),
R.applySpec({
...spec,
username: R.prop('username'),
password: R.prop('password')
})
)
const lib = {
getFormattedPropsForUser: forUser(),
getFormattedQueryParamsForUser: forUser({ _id: R.prop('_id') }),
}
const test = { _id: 'id', username: 'username', password: 'password' }
console.log(lib.getFormattedPropsForUser(test))
console.log(lib.getFormattedQueryParamsForUser(test))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
I think you can simplify your functions quite a bit, and abstract the common parts out relatively easily. Here getActualProps does much the same as your applySpec/pickBy(identity) shuffle, with the actual fields parameterized. Then the two functions (or library methods) can be written in terms of it.
const getActualProps = (names) => pickBy((v, k) => includes(k, names))
const getFormattedPropsForUser = getActualProps(['username', 'password'])
const getFormattedQueryParamsForUser = getActualProps(['_id', 'username'])
// Test
const fred = {_id: 1, name: 'fred', username: 'fflint', password: 'dino'}
const wilma = {_id: 2, name: 'wilma', username: 'wilma42'}
const barney = {_id: 3, name: 'barney', password: 'bam*2'}
console.log(getFormattedPropsForUser(fred)) //~> {password: "dino", username: "fflint"}
console.log(getFormattedQueryParamsForUser(fred)) //~> {_id: 1, username: "fflint"}
console.log(getFormattedPropsForUser(wilma)) //~> {username: "wilma42"}
console.log(getFormattedQueryParamsForUser(wilma)) //~> {_id: 2, username: "wilma42"}
console.log(getFormattedPropsForUser(barney)) //~> {password: "bam*2"}
console.log(getFormattedQueryParamsForUser(barney)) //~> {_id: 3}
<script src="https://bundle.run/ramda#0.26.1"></script><script>
const {pickBy, includes} = ramda </script>

Another form of Object literals in JSON?

I'm trying to figure out how to make this work:
var emails = $("#register_Email").val();
var split = emails.split("#");
var username = split[0];
var first = $("#register_FirstName").val();
var last = $("#register_LastName").val();
var phone = $("#register_PhoneNumber").val();
ref2.set({
username: {
active: true,
email: emails,
first_name: first,
last_name: last,
phone: phone,
role: "technician"
}
});
I can get all of the variables but the problem is I want to pass it into the set() method as seen above. The name of the whole node should be the value of the username, not the word username.
I've tried using literals in this way:
ref2.set({
[username]: {
active: true,
email: emails,
first_name: first,
last_name: last,
phone: phone,
role: "technician"
}
});
But that doesn't work. It just crashes saying I can't pass [ or ] as variable names.
Can't do it with object literal. But you can remember that foo.bar is equivalent to foo['bar'], and write this instead:
var opts = {};
opts[username] = {
active: true,
email: emails,
first_name: first,
last_name: last,
phone: phone,
role: "technician"
};
ref2.set(opts);

Categories