Lodash: Join values by given key - javascript

I am trying to search easy function on Lodash.js for joining values by given key or something...
Example:
const obj = {firstname : 'John', title: 'Mr.', lastname: 'Due'}
Expected results:
Mr. John Due
Any function like _.join() but better and I can do something like..
_.joinX(obj, ['title', 'firstname', 'lastname'], ' ')
Why not just...?
obj.title + ' ' + obj.firstname + ' ' + obj.lastname
Because sometimes my object is so long like... (And I will not give more variable)
obj.current.user.info.title + ' ' + obj.current.user.info.firstname + ' ' + obj.current.user.info.lastname

You can port the following to Lodash.
const joinByKeys = (obj = {}, props = [], separator = '') => {
// empty array.
let arr = [];
// push props to array
props.forEach(p => arr.push(obj[p]))
// return the joined array.
return arr.join(separator);
}
const obj = {firstname : 'John', title: 'Mr.', lastname: 'Due'}
console.log( joinByKeys(obj, ['title', 'firstname', 'lastname'], ' ') );

I think I got it:
const obj = {firstname : 'John', title: 'Mr.', lastname: 'Due'}
let name = _(obj).pick(['title', 'firstname', 'lastname']).values().join(' ')
console.log(name)
Not really special function as I expected but have to run tho Lodash's functions a bit

Related

Why doesn't console.log() of a map object return the data?

I have pet data stored on as a mongodb object as shown below:
{
"_id" : ObjectId("0000439359317900131f111"),
"name" : "Travis",
"description" : "Travis is a support animal",
"petId" : "225123",
"petDetails" : {
"color" : "brown"
}
}
When I try to console.log petDetails (petDetails is a map) object using the following:
const pet = await context.AnimalService.findOne({where:{_id : userSubscription.planId}})
const petDetails = pet.petDetails
console.log('Logging Pet Details', petDetails)
The result is returned as:
Logging Pet Details {
'$__parent': '{\n' +
' _id: 0000439359317900131f111,\n' +
" name: 'Travis',\n" +
" description: 'Travis is a support animal',\n" +
" petId: '225123',\n" +
" petDetails: Map(1) { 'color' => 'brown' },\n" +
' __v: 0,\n' +
'}',
'$__path': 'petDetails',
'$__schemaType': '[object Object]'
How can have petDetails simply returned as an object and not the weird way it is currently formatted?
maybe your petDetail is Mongo object, you should convert it to plain object by using petDetail.toObject
Ref: https://stackoverflow.com/a/7503523/1743046

reduce() object by arraykey is not using the first key javascript

const cliente = {
nome: "Andre",
idade: 36,
cpf: "123.456.789.10",
email: "andre#gmail.com"
}
const chaves = ["nome", "idade", "cpf", "email"];
const clienteString = chaves.reduce((acum, curr) => acum += curr + ":" + cliente[curr] + ";")
console.log(clienteString);
the current output is: **nome**idade:36;cpf:123.456.789.10;email:andre#gmail.com;
the value of the key "nome:" is not being considered in the string
it should output this: nome:Andre;idade:36;cpf:123.456.789-10;email:andre#gmail.com;
what am i doing wrong?
This is a simpler version that does what you want:
const cliente = {
nome: "Andre",
idade: 36,
cpf: "123.456.789.10",
email: "andre#gmail.com",
};
console.log(
Object.entries(cliente)
.map(([key, value]) => `${key}:${value};`)
.join("")
);
Object.entries returns an array of ["key", "value"]. Then we map over that and turn it into an array of "key:value;". Then we join the array of "key:value;" into a string.

How to wait created variable to change before rendering data in vue?

I have a variable that is called "name" inside my data(). And this is updated once I fetch this value from firebase using created() like this:
created: async function fetchDataFromFirebase() {
this.email = this.getCurrentUser().email
await this.doctorsCollection.doc(this.email).get().then(async (doc) => {
this.name = await doc.data().title + ' ' + await doc.data().firstName + ' ' + await doc.data().lastName
this.speciality = await doc.data().speciality
this.phone = await doc.data().phone
this.profilePicture = doc.data().img == null || doc.data().img === '' ? 'https://firebasestorage.googleapis.com/v0/b/healthy-wo.appspot.com/o/doctors%2FMantraHW-T-Coral-01.png?alt=media&token=2ae855cb-c96d-4b97-b813-c844f9e0e871':doc.data().img
// getCurrentAge will give the difference in years between today and the Date object you're passing
this.age = this.getCurrentAge(new Date((await doc.data().birthDate).toMillis())) + ' años'
// memberDate is a variable that holds the date this user was registered but in Date object format
let memberDate = new Date((await doc.data().subscriptionStart).toMillis())
this.member_duration = memberDate.getDate() + '/' + (memberDate.getMonth()+1<10 ? '0'+(memberDate.getMonth()+1):memberDate.getMonth()+1) + '/' + memberDate.getFullYear()
})
},
My problem here though, is that I must wait for this variable to update and then asign it to a new variable inside data() too, called query. But everytime I reference it as this.name I get an error because name is undefined. Here's my query I'm trying to submit
query: firebase.firestore().collection('feed').limit(3).where('author', '==', /*here goes name*/),
I must have this query variable in data() because then I got to pass it as a prop to a new component:
<post-card
v-bind:query="query"
></post-card>
Here's my data() too:
data() {
return {
doctorsCollection: firebase.firestore().collection('doctors'),
name: 'hello',
query: firebase.firestore().collection('feed').limit(3).where('author', '==', this.name),
speciality: '',
member_duration: '',
email: '',
phone: '',
age: '',
profilePicture: '',
dialog: false
}
},
I've just solved it by placing the query change inside created.
created: async function fetchDataFromFirebase() {
this.email = this.getCurrentUser().email
await this.doctorsCollection.doc(this.email).get().then(async (doc) => {
this.name = await doc.data().title + ' ' + await doc.data().firstName + ' ' + await doc.data().lastName
this.speciality = await doc.data().speciality
this.phone = await doc.data().phone
this.profilePicture = doc.data().img == null || doc.data().img === '' ? 'https://firebasestorage.googleapis.com/v0/b/healthy-wo.appspot.com/o/doctors%2FMantraHW-T-Coral-01.png?alt=media&token=2ae855cb-c96d-4b97-b813-c844f9e0e871':doc.data().img
// getCurrentAge will give the difference in years between today and the Date object you're passing
this.age = this.getCurrentAge(new Date((await doc.data().birthDate).toMillis())) + ' años'
// memberDate is a variable that holds the date this user was registered but in Date object format
let memberDate = new Date((await doc.data().subscriptionStart).toMillis())
this.member_duration = memberDate.getDate() + '/' + (memberDate.getMonth()+1<10 ? '0'+(memberDate.getMonth()+1):memberDate.getMonth()+1) + '/' + memberDate.getFullYear()
})
this.query = firebase.firestore().collection('feed').limit(3).where('author','==', this.name.toString())
},
data() {
return {
doctorsCollection: firebase.firestore().collection('doctors'),
name: 'hello',
query: 'null',
speciality: '',
member_duration: '',
email: '',
phone: '',
age: '',
profilePicture: '',
dialog: false
}
},
And also using a v-if statement inside my component. So it won't be rendered unless query is different from an initial string.
<post-card
v-if="query !== 'null'"
v-bind:query="query"
></post-card>

I want to know the second argument of application

function printProfile(name, age, ...args) {
return `${this.type} ${name} Age:${age}${args.length === 0 ? '' : ' ' + this.feature + ':' + args.join(',')}`
}
const developer = {
type: 'Developer',
feature: 'Language'
};
const artist = {
type: 'Artist',
feature: 'Song'
};
printProfile.apply(developer, ? ) // --> 'Developer jack Age:30'
printProfile.apply(developer, ? ) // --> 'Developer jin Age:20 Language:JavaScript'
printProfile.apply(artist, ? ) // --> 'Artist BTS Age:7 Song:ON,Dynamite'
The second argument is '?'. I wonder what it is.
The second parameter of the apply is an array of items that will match the position of your function arguments. And any left over goes to the args param. Here is one example, and from this you should be able to grasp the concept to figure out the rest.
printProfile.apply(developer, ['Joe', 34, 'JavaScript'])
Resources
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
Test Snippet
function printProfile(name, age, ...args) {
return `${this.type} ${name} Age:${age}${args.length === 0 ? '' : ' ' + this.feature + ':' + args.join(',')}`
}
const developer = {
type: 'Developer',
feature: 'Language'
};
const artist = {
type: 'Artist',
feature: 'Song'
};
const result = printProfile.apply(developer, ['Joe', 34, 'JavaScript'])
console.log(result)

Passing particular argument to a function having multiple arguments in React

In React, I have created function mentioned below:
infoPrint (firstname = '--', middlename = '--', surname = '--')
{
console.log('Firstname: ', firstname, ', Middle name: ', middlename, ', Surname: ', surname);
}
I am calling this function in componentWillMount:
componentWillMount() {
var firstname = 'Naisarg';
var surname = 'Parmar';
this.infoPrint(firstname,surname);
}
I am getting this output:
Firstname: Naisarg, Middle name: Parmar, Surname: --
But I'm expecting this one:
Firstname: Naisarg, Middle name: --, Surname: Parmar
You can achieve that by passing a literal object as argument of your function:
class User extends Component {
componentWillMount() {
var firstname = 'Naisarg';
var surname = 'Parmar';
this.infoPrint({ firstname, surname });
}
infoPrint({ firstname = '--', middlename = '--', surname = '--' }) {
console.log('Firstname: ', firstname, ', Middle name: ', middlename, ', Surname: ', surname);
}
}
It's a very common pattern that helps a lot with optional parameters.
-
If you prefer not to use an object, then you must pass all the arguments in the correct order:
class User extends Component {
componentWillMount() {
var firstname = 'Naisarg';
var surname = 'Parmar';
this.infoPrint(firstname, null, surname);
}
infoPrint(firstname = '--', middlename = '--', surname = '--') {
console.log('Firstname: ', firstname, ', Middle name: ', middlename, ', Surname: ', surname);
}
}
To achieve what you require, you will either need to pass -- or null for the middlename argument:
componentWillMount() {
var firstname = 'Naisarg';
var surname = 'Parmar';
this.infoPrint(firstname, null, surname);
this.infoPrint(firstname, '--', surname);
}
or alternatively, you could refactor your method signature by passing these arguments indirectly via an object argument:
function infoPrint(name = { first: '--', middle: '--', last: '--' }) {
console.log('Firstname: ', name.first, ', Middle name: ', name.middle, ', Surname: ', name.last);
}
infoPrint({
first: 'Naisarg',
last: 'Parmar'
});
The "object argument" method shown above resolves the issue you're facing by retaining a (key) relationship between the arguments themselves, and the way in which each keyed argument is actually used in your infoPrint() function.
Without this, the JavaScript run-time has no way of knowing that you intend the surname variable to actually be passed to infoPrint() as the "third surname argument" - simply put, the arguments that you pass are assigned from first to last. Substituting the variable with values as shown below might give more insight as to what's happening, and why your original code doesn't work as expected:
// var firstname = 'Naisarg';
// var surname = 'Parmar';
// Substitute variables with values to better understand how
// arguments are being passed to the function
this.infoPrint(
'Naisarg' /* <-- firstname */,
'Parmar' /* <-- middlename */,
/* no value for surname, so use default "--" */
); /* Prints: "Firstname: Naisarg , Middle name: Parmar , Surname: -- " */

Categories

Resources