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; }
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})
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 })
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>
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);