Why is undefine for the destructing variables - javascript

Whay the values of destructing variables are undefine?
I also referenced in "..developer.mozilla.org", but, what is wrong?
here is my javascript code snippet =>
let myid, myname, myage;
// let person = [1, 'Kyaw Kyaw', 25];
// [myid, myname, myage] = person;
({ myid, myname, myage } = { id: 1, name: "Kyaw Kyaw", age: 25 });
console.log(myid);
console.log(myname);
console.log(myage);
When I got output for these variables, they are all 'undefine'!
What is wrong? Very interesting!!

Destructuring objects is based on the name of the variable and the property, not the order.
myid is a different name to id so it doesn't match.
yourobject.myid is undefined.
If you want to store the value in a variable name that doesn't match the property name, then you have to specify that explicitly with the format: property_name: variable_name
const my_object = { id: 1, name: "Kyaw Kyaw", age: 25 };
console.log(my_object.myid);
let { id: myid, name: myname, age: myage } = my_object;
console.log(myid);
console.log(myname);
console.log(myage);

Related

How to filter few properties of an object which is in Array of objects if one property equals property from another object

I have a object which has some properties for one user, and I have array of objects which is returned from API.
My goal is to check which object of Array of objects has the same property as the one single initial object, and then it should return only part of it's properities.
I have tried to use .map on Array of objects but it seems not workig.
Below is the code example. I have also prepared codesandbox if You wish.
const user =
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
car: "audi"
}
;
const usersAnimal = [
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
animal: "cat",
animalSize: "small",
animalName: "Bat"
},
{
name: "john",
lastName: "smith",
fullName: "john smith",
animal: "dog",
animalSize: "middle",
animalName: "Jerry"
},
{
name: "Anna",
lastName: "Nilsson",
fullName: "Anna Nilsson",
animal: "cow",
animalSize: "big",
animalName: "Dorrie"
}
];
const filtered = usersAnimal.map((userAnimal)=>userAnimal.fullName === user.fullName && return userAnimal.animalName & userAnimal.animalSize & userAnimal.animal);
thanks
https://codesandbox.io/s/admiring-edison-qxff42?file=/src/App.js
For case like this, it would be far easier if you filter it out first then proceed using map:
const filtered = usersAnimal
.filter((animal) => animal.fullName === user.fullName)
.map(({ animalName, animalSize, animal }) => {
return {
animalName,
animalSize,
animal
};
});
I am providing a for loop solution as I haven't learnt many array methods in javascript.
For me the simplest option is to use a for loop and an if check to loop through the arrays values to check for included values.
for (let v in usersAnimal) {
if (usersAnimal[v].fullName === user.fullName) {
console.log(usersAnimal[v])
}
}
The code above will log the entire usersAnimal object containing the fullname we are looking for.
{
name: 'jan',
lastName: 'kowalski',
fullName: 'jan kowalski',
animal: 'cat',
animalSize: 'small',
animalName: 'Bat'
}
commented for further understanding
for (let v in usersAnimal) {
//loops though the array
if (usersAnimal[v].fullName === user.fullName) {
//when the index value 'v' has a fullname that matches the user fullname value
// it passes the if check and logs that object value
return console.log(usersAnimal[v])
//return true...
}
//return null
}
//etc
If you want to filter, I recommend you to use filter.
The map method will create a new array, the content of which is the set of results returned by each element of the original array after the callback function is operated
const user = {name:"jan",lastName:"kowalski",fullName:"jan kowalski",car:"audi"};
const usersAnimal = [{name:"jan",lastName:"kowalski",fullName:"jan kowalski",animal:"cat",animalSize:"small",animalName:"Bat"},{name:"john",lastName:"smith",fullName:"john smith",animal:"dog",animalSize:"middle",animalName:"Jerry"}];
// Get an array of matching objects
let filtered =
usersAnimal.filter(o => o.fullName === user.fullName);
// You get the filtered array, then you can get the required properties
filtered.forEach(o => {
console.log(
'animal:%s, animalSize:%s, animalName:%s',
o?.animal, o?.animalSize, o?.animalName
);
});
// Then use map to process each element
filtered = filtered.map(o => {
const {animal, animalSize, animalName} = o;
return {animal, animalSize, animalName};
});
console.log('filtered', filtered);

Advanced Destructuring of objects in ES6

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.

Clone a object only with few properties

Is there a way to clone an object with only few properties of the object in JS?
For example..
var Person = {
name: "Bob",
age: 32,
salary: 20000
};
I have to create another person object with just the name and age property so that it will look something like this :
var clonedPerson = {
name: "Bob",
age: 32
};
I could do a deep clone of the object and delete. But I wanted to know if there are better ways to do it.
Using the latest ES6, you can achieve this by the following code..
const Person = {
name: "Bob",
age: 32,
salary: 20000
};
const { salary , ...clonedPerson } = Person
console.log(clonedPerson)
More simple?
var Person = {
name: "Bob",
age: 32,
salary: 20000
};
var ClonedPerson = jQuery.extend({}, Person);
delete ClonedPerson.salary;
console.log(JSON.stringify(Person));
console.log(JSON.stringify(ClonedPerson));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
an alternative approach using Array member methods:
var clone = Object.keys(Person) // convert to an Array of Person keys
.filter(function(key){return ["salary"].indexOf(key) == -1;}) // exclude key salary
.reduce(function(clone, current){clone[current] = Person[current]; return clone;}, {}); // convert back the array to a cloned literal object

Can't set property name with a variable in JSON

function one(data) {
someotherfunction({
data.id: {
name: data.nm,
age: data.age
});
}
one({ id: 2, name: "Stack", age: "20" });
Why can't I set data.id as the property name of that sub-object? I tried many ways of setting the id but it only works if I set it to some string name....
var i = data.id;
someotherfunction({i:{name:data.nm,age:data.age});
It doesn't recognize the variable either?
I don't think that's a valid propertyName or identifier and it's certainly not a string literal. Try it like this:
function one(data){
var nObj = { };
nObj[data.id] = { name : data.nm, age: data.age };
someotherfunction(nObj);
}
one({id:2,name:"Stack",age:"20"});
//nObj = { 2 : { name : "Stack, age : "20" } }
From RobG's answer at: https://stackoverflow.com/a/6500668
In an object literal (ECMA-262 §11.1.5 calls it an "object
initialiser") the key must be one of:
IdentifierName
StringLiteral
NumericLiteral
You could do something like:
function one(data) {
var d = {};
d[data.id] = { name: data.name, age: data.age };
someotherfunction(d);
}
one({ id: 2, name: 'Stack', age: '20' });
Fiddle with the code at:
http://jsfiddle.net/sna04g8m/1
You may be looking for computed property names, a new feature in ECMAScript 2015 that is supported in some browsers, e.g.:
// Requires support for ECMAScript 2015 computed property names
function one(data) {
return {
[data.id]: {
name: data.name,
age: data.age
}};
}
document.write(JSON.stringify(one({ id: 2, name: "Stack", age: "20" })));

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