Advanced Destructuring of objects in ES6 - javascript

I have the following object:
personObj = {
_id : '123',
first_name: 'John',
last_name: 'Doe',
}
I would like to destructure it to the following variables:
id, <-- _id
name: {
first, <-- first_name
last <-- last_name
}
(I want first_name and last_name to reside inside a 'name' object)
I've tried the following syntax:
const {
id: _id,
name: {
first: first_name,
last: last_name
}
} = personObj
However this causes an error.
What am I doing wrong?

Update
Chapter 10. Destructuring of book "Exploring ES 6" provides many advanced examples of how to use destructuring and explains how it works internally.
Destructuring can extract values directly into the properties of an object. The properties are not required to exist but all destination objects must already exist when the destructuring assignment happens.
Armed with this knowledge, the code that answers the question is:
let personObj = {
_id: '123',
first_name: 'John',
last_name: 'Doe',
}
// Create the objects that receive the values on destructuring
let c = { name: {} }
// Do the magic
({ _id: c.id, first_name: c.name.first, last_name: c.name.last } = personObj)
console.log(c)
// {id: "123", name: {first: "John", last: "Doe"}}
The parentheses around the assignment expression that uses destructuring are required, without them the engine reports a syntax error at the first :.
The original answer follows. It doesn't completely answer the question but I leave it here for reference. It shows how to use the rest properties (...) in destructuring expressions and it was accepted by the OP, as incomplete as it is.
The original answer
Destructuring with properties renaming works the other way around: the original name is placed before the colon, the new name is after it.
let personObj = {
_id: '123',
first_name: 'John',
last_name: 'Doe',
}
// Destructure personObj using different names for the properties
const {
_id: id,
first_name: first,
last_name: last
} = personObj
console.log('id: ' + id);
console.log('first: ' + first);
console.log('last: ' + last);
// Output
// id: 123
// first: John
// last: Doe
You can then assemble the pieces (id, first, last) into a new object:
let c = {
id,
name: {
first,
last
}
}
console.log(c);
// Output
// { id: '123', name: { first: 'John', last: 'Doe' } }
Update
The most similar result to what you describe in the question can be achieved by:
let { _id: id, ...name } = personObj
console.log(id)
console.log(name)
// Output
// 123
// { first_name: 'John', last_name: 'Doe' }
But this way the properties of name use the same names they have in personObj. Even more, it doesn't work any more if you add to personObj properties after last_name that you don't want to copy in name.

Related

Remove element from objects in javascript multidimensional array

I have read several solutions to this problem here. When I try it, I continue to receive an error for the pop() method.
I have what is essentially a multidimensional array in javascript.
I am tasked with returning the array with the sensitive info removed (e.g. remove the SSN, in this example)
I thought I could use a foreach loop, and the pop() function to remove the last element of the child arrays, the SSN.
testing it using node on the commandline, the stdout is telling me that element.pop() is not a function. i've tried it with pop(), slice(), filter(), all with no success.
when running $> node filename.js
H:\Apache2\htdocs\test\filename.js:50
noppi[i] = element.pop();
^
TypeError: element.pop is not a function
let recs = [
{
ID: 1,
NAME: 'John',
EMAIL: 'john#example.com',
SSN: '123'
}, {
ID: 2,
NAME: 'Sally',
EMAIL: 'sally#example.com',
SSN: '456'
}, {
ID: 3,
NAME: 'Angie',
EMAIL: 'angie#example.com',
SSN: '789'
}
];
let i = 0;
let noppi = [];
recs.forEach(element => {
noppi[i] = element.pop();
i++;
});
console.log(noppi);
At the risk of sounding redundant, I'll briefly reiterate what the earlier answers have already stated.
The input data structure isn't a multi-dimensional array [ [ ... ], [ ... ] ] , it's an array of objects [ {...}, {...} ]. So you can't use Array methods like .pop() on the objects {...}.
Here's a simple one-liner that uses .forEach() and delete.
recs.forEach(obj => delete obj.SSN)
delete is an operator with one purpose: to remove an object's property like for example SSN: '123-45-6789'. Simple and perfect.
Note, .forEach() mutates the array, meaning that it's the original data being changed (see Minja's comment).
let recs = [
{
ID: 1,
NAME: 'John',
EMAIL: 'john#example.com',
SSN: '123'
}, {
ID: 2,
NAME: 'Sally',
EMAIL: 'sally#example.com',
SSN: '456'
}, {
ID: 3,
NAME: 'Angie',
EMAIL: 'angie#example.com',
SSN: '789'
}
];
recs.forEach(obj => delete obj.SSN);
console.log(recs)
Try this:
recs.forEach(element => {
noppi.push = element;
});
You are trying to use pop() on an object not an array
As per your need you need to remove SSN from your object, try below code it should work for you.
recs.forEach(element => {
const { SSN, ...rest } = element;
noppi.push(rest);
});
Here we are removing SSN from object and rest will push in noppi.

Why getting "Destructuring expressions can only have identifier references" when trying to destruct an object?

I have the following object:
const john = {
family: [
{ firstName: 'david', secondName: 'jana' },
{ firstName: 'eyal', secondName: 'shani ' },
],
};
I want to get 'david' string in one operation. So i tried the following code:
const { family:[0]{firstName}}} = john;
But i'm getting the error :
"Destructuring expressions can only have identifier references"
Can someone tell me in simple words (cause i'm new in the language) what i'm doing wrong?
To extract a deeply nested value with destructuring, the syntax is nearly identical to when declaring an object with those properties. family:[0] isn't valid syntax - instead, you need to surround the contents of family in array delimiters:
const john = {
family: [{
firstName: 'david',
secondName: 'jana'
},
{
firstName: 'eyal',
secondName: 'shani '
},
],
};
const { family:[{firstName}]} = john;
console.log(firstName);
But I'd highly recommend against using nested destructuring like this. It's so hard to write and read and understand. Better to use plain dot notation at least for the outer accesses, eg
const john = {
family: [{
firstName: 'david',
secondName: 'jana'
},
{
firstName: 'eyal',
secondName: 'shani '
},
],
};
const { firstName } = john.family[0];
console.log(firstName);

How can i get both object length together from chain of object

Say I create a Object as follows
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
And create another object with the above object to add as a prototype object
const myObj2 = Object.create(myObj1, {
age:{
value:33
},
edu:{
value: "MBA"
}
});
now I want to count length of both object together, how can i?
I understand you want to get count of all keys in your object(s). As there is no length property available for objects (only for arrays), you should use Object.keys(), which returns an array with all keys:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
Object.keys(myObj1).length; // would return '3'
I believe that instead of Object.create(), you actually want to use Object.assign(), which will assign all keys from myObj1 to myObj2:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
const myObj2 = {
age:{
value:33
},
edu:{
value: "MBA"
}
}
Object.assign(myObj2, myObj1);
document.write(Object.keys(myObj2).length + '<br>'); // return '5'
document.write(Object.keys(myObj1).length); // return '3'
If I understand the OP goal:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
const myObj2 = {
age:{
value:33
},
edu:{
value: "MBA"
}
};
const result = {...myObj1, ...myObj2};
console.log(result);
const length = Object.keys(result).length;
console.log(length);
{ firstName: 'Shaheb',
lastName: 'Ali',
professions: 'Web Developer',
age: { value: 33 },
edu: { value: 'MBA' }
}
5
const obj = Object.create(myObj1, myObj2);
create prototyping object looks like below
{age: 33, edu: "MBA"}
age: 33
edu: "MBA"
proto:
firstName: "Shaheb"
lastName: "Ali"
professions: "Web Developer"
proto: Object
but assigning a object is like a combining 2object into one. is this not possible to get the length from plan object and prototyping object together?
but your ans was awesome, help me a lot to make it better understand. if it is not possible then i will follow your suggestions.

How to call for object keys in javascript (codecademy)

I'm following an online course in Javascript from Codecademy but i'm stuck in an assignment.
I'm trying to list the firstName key from my "friends list".
I have to do this with a "for in" statement in a function.
The firstName key is within the object "Steve", which in in an object "Friends".
This is the code that i have at the moment:
var friends = {
steve: {
firstName: 'Steve',
lastName: 'Jobs',
number: '1',
address: ['Fregataan','65','8546','RG','Amsterdam','The Netherlands'],
},
bill: {
firstName: 'Bill',
lastName: 'Gates',
number: '2',
address: ['Fregataan','665','8546','RG','Amsterdam','The Netherlands'],
},
};
function list(friends){
for (var firstName in friends){
console.log(friends.keys(firstName))
}
}
list(friends.keys);
This is the assignment I get from the course:
1. Create a function list that takes a single parameter.
2. In the body of the function, write a for/in loop.
3. In the loop, use console.log to print out the key. (For example, if you only have bill and steve as entries, list should just print out "bill" and "steve".)
The object "friends" was already written in a previous assignment. The function has to be written in this assignment. Can someone please find my mistake and tell me what i did wrong?
Greetings,
Luuk
I think it might be a tricky question. You are trying to print the firstName key which (if done correctly) will print out "Steve" and "Bill", but the assignment, as you described it, is to print out the key (i.e. "steve" and "bill"). So if that's the case, you should just print out the key:
function list(friends){
for (var key in friends){
console.log(key);
}
}
Hope this helps.
You should play around with it a bit more.
No need to use 'keys'.
var friends = {
steve: {
firstName: 'Steve',
lastName: 'Jobs',
number: '1',
address: ['Fregataan','65','8546','RG','Amsterdam','The Netherlands'],
},
bill: {
firstName: 'Bill',
lastName: 'Gates',
number: '2',
address: ['Fregataan','665','8546','RG','Amsterdam','The Netherlands'],
},
};
function list(friends){
console.log(friends);
for (var friend in friends){
console.log(friend);
var f = friends[friend];
console.log(f.firstName);
}
}
list(friends);

Updating javascript object property?

I have a structure like the following:
skillet.person = {
name: {
first: '',
last: ''
},
age: {
current: ''
},
birthday: {
day: '',
month: '',
year: ''
}
}
I was wondering how I would update these values ? i.e. I though the following was correct
skillet.person.name.push({ first: 'blah', last: 'ha'});
but it's wrong ? How can I fix this ?
Using ES7+ syntax and a functional approach:
const new_obj = { ...obj, name: { first: 'blah', last: 'ha'} }
On recent browsers with ECMAScript 2015, you can do:
Object.assign(skillet.person.name, { first: 'blah', last: 'ha'});
which will preserve any existing attribute not listed in the right object.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
[EDIT] With ES7, you can do even shorter (but is it clearer?...):
{...skillet.person.name, ...{ first: 'blah', last: 'ha'}};
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
As #ramon-diogo wrote with ES7+
I like to update nested values like:
let user = {
name: {
first: 'john',
last: 'smith'
},
age: 18,
city: 'new york'
}
const age = 20;
user = {...user, age}
console.log(user.age)
// output: 20
const newData ={
age: 22,
city: 'san francisco'
};
user = {...user,...newData}
console.log(user.name.first)
// output: john
console.log(user.age)
// output: 22
console.log(user.city)
// output: 'san francisco'
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"
or
skillet.person.name = {first : "blah", last : "ha"}
If you want to mix an object into another one, you can use jQuery's deep extend function. "Deep" means that it does not overwrite name with the new object, but rather overwrites the properties inside such an object.
$.extend(true, skillet.person, {
name: {
first: 'updated'
},
birthday: {
day: 'updated',
year: 'updated'
}
});
Now, skillet.person has the appropriate properties updated, while the other properties are untouched.
push is a method of Arrays that adds a new item to an array.
If you want to replace the value then:
skillet.person.name = { … };
If you want to store multiple (full) names in the object, then you'll need the property to hold an array of objects instead of a single object.
I think that is simpler
let skillet = {
person: {
name : {
first: '',
last : ''
},
age : {
current: ''
},
birthday: {
day : '',
month: '',
year : ''
}
}
};
let update = {
person: {
name: {
first: 'blah',
last : 'ha'
}
}
};
let result = Object.assign(skillet.person, update.person);
console.log(result);
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"
The easiest way.
skillset.person.name = {};
This is the easiest way to assign value to the property of an object.

Categories