I'm trying to destructure and ignore few values, how do I do that?
For example:
const test = { name: 'John', age: 29, gender: 'male'}
function getData(...args) {
const {,,gender} = args[0];
console.log(gender); // should print male.
}
getData(test);
I want to ignore (not declare variables for) name and age parameters (so that my ESLint does not throw an error) at the same time use ES6.
The syntax , does not seem to work either. Any other workarounds for this problem?
You have a single arg (the object), and you should object destructuring to get gender:
const test = { name: 'John', age: 29, gender: 'male'}
function getData(arg) {
const { gender} = arg;
console.log(gender); // should print male.
}
getData(test);
Related
I have a type coming from a 3rd party API which has a lot of properties (50+) and they take all values as string. The even number and booleans became strings ("5" and "false" respectively) and I want to fix the scary thing.
So I created a type like this to receive the response from API and to hold after fix
interface Person {
age: string | number,
name: string,
hasChildren: string | boolean,
...
}
And I want to transform this
const responseFromApi: Person = {
age: "20",
name: "John",
numberOfChildren: "true"
...
}
to
const afterTreatment: Person = {
age: 21,
name: "John",
numberOfChildren: true
...
}
This is an example... My object, again, is much bigger than this, with a lot of props in this situation so treat them individually is not the kind of solution I'm looking for.
My intention is to iterate over the object and change to number or boolean what can be changed following type.
You could for-loop the array, check if the element.age is a string and if yes parseInt the age and set it again.
A better solution would maybe be to map though the list, and do the same thing as above, just so it creates a new array, which you could then overwrite/do what you need.
Idea:
const changed = persons.map((p: Person) => {
if (typeof p.age === "string") {
return {
...p,
age:parseInt(p.age)
}
}
return p
});
This should work as long as the variable conventions are consistent with person1, person2, person3 etc and also you need to know the total number of added persons for the forloop to work
interface Person {
age: string | number,
name: string
}
const person1: Person = {
age: 20,
name: "Jonh",
}
const person2: Person = {
age: "21",
name: "Marie",
}
const lengthOfPersons: number = 2;
const newArray = [];
for(let i = 0; i < lengthOfPersons; i++)
{
const n = i + 1;
const row = eval('person'+n);
newArray.push({...row, age: +row.age})
}
console.log(newArray);
I am refactoring my code, which involves converting a big list of let statements into an object called personDetails:
personDetails = {
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
}
Currently, I am destructuring the values returned from my array like this:
[firstName, lastName] = getNames(zipcode, age, gender)
This works fine. But now that I am switching to an object, how do I update that object with the returned values? I will be passing in the object as an argument like this:
getNames(personDetails)
Do I have to do something like this?
personDetails = getNames(personDetails)
The called function might look something like this (abbreviated):
const getNames(personDetails) => {
personDetails.firstname = 'Jack'
personDetails.lastName = 'Jones'
}
1) Your arrow function had a typo, you must declare it with an = before the argument, like this:
const getNames = (personDetails) => { // Correct
const getNames(personDetails) => { // Incorrect
2) Inside your function, you weren't modifying an object key, but creating a new one instead. Remember that objects keys differs if you use upper or lowercase letters, firstName and firstname are not the same key.
3) Last, when you create an argument in your function, do not declare it with the same name of the global object, since it could create unexpected results. Then, you don´t need to destructure your object, just return the complete object.
let personDetails = { // Using let
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
};
const getNames = (obj) => { // obj is the argument
obj.firstName = 'Jack';
obj.lastName = 'Jones';
return obj; // Return complete object
}
personDetails = getNames(personDetails);
console.log(personDetails);
If you want to destructure the object, you can do it too the same way you do it with the array, but I wouldn´t recommend it because it makes the code less clear:
const personDetails = { // Using const
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
};
const getNames = (obj) => { // obj is the argument
obj.firstName = 'Jack';
obj.lastName = 'Jones';
return [obj.firstName, obj.lastName]; // Return part of object as an array
}
[personDetails.firstName, personDetails.lastName] = getNames(personDetails);
console.log(personDetails);
I've run into questions similar to this one, but they generally pertain on how to remove an underscore whereas I am having the issue of removing the underscore in a for loop. When console logging in my function it will show that the fields I want changed do in fact change but when I return the object it only returns an object where all keys have snake case. I think this may be a scope issue but after playing around with the different placement of variables I keep getting stuck. Below is an example of the original object I would like to change:
const originalObj = {
accountNumber: '12345',
company: [
{
address: {
line1: '123',
line2: 'Spring Street'
}
}
],
ownerInfo: [
{
firstName: 'John',
lastName: 'Doe'
enrollment: '2015-10-15'
}
],
tax: {
code: '12345'
}
}
Using the npm package change-case-object I am able to successfully change all keys with camel case to snake case. However, I do not want any key that has a numeric value to include an underscore (like with the cases of line1 and line2). With this function
import changeCaseObject from 'change-case-object';
export function restructure(originalObj) {
const regex = /\d/g;
let newObj;
if(typeof originalObj === "object"){
newObj = changeCaseObject.snakeCase(originalObj);
for(const key in newObj){
if(typeof newObj[key] === "object" && newObj[key] !== null){
restructure(newObj[key])
//if the value is an object use recursion
} else {
if(regex.test(key)){
let newKey = key.replace(/_/g, '');
newObj.newKey = newObj.key;
delete newObj.key;
}
}
}
}
return newObj;
}
When I add a console log in the case where the key matches the regex, it will show that "line_1" does in fact change to "line1" along with "line_2". However when returning newObj it just returns the object in which all values now have snake case (as shown below)
{
account_number: '12345',
company: [
{
address: {
line_1: '123',
line_2: 'Spring Street'
}
}
],
owner_info: [
{
first_name: 'John',
last_name: 'Doe'
enrollment: '2015-10-15'
}
],
tax: {
code: '12345'
}
}
I feel like there is something very simple that I am overlooking but defining newObj outside of the if else statement has not led to success either. Thank you for your time.
This question already has an answer here:
Where can I get info on the object parameter syntax for JavaScript functions?
(1 answer)
Closed last year.
I saw this code on a package:
const SortableList = SortableContainer(({items}) => {
return (
<ul>
{items.map((value, index) =>
<SortableItem key={`item-${index}`} index={index} value={value} />
)}
</ul>
);
});
What is happening to items by putting curly braces around it in the function parameters?
This is destructuring assignment syntax.
As another example, the following two lines of code are equal:
const { items } = args
const items = args.items
Simply put, it is a simplified way of accessing specific field of a given variable for further use in that scope.
In your original example, it is declaring a variable items for use in the function body that is the items field of that first argument.
const SortableList = SortableContainer(({items}) => {
// do stuff with items here
is equal to
const SortableList = SortableContainer((input) => {
const items = input.items
// do stuff with items here
This question is likely a repost: What do {curly braces} around javascript variable name mean
But as an answer, it's destructuring assignment. If your object being passed in mirrors the variable being referenced, you can retrieve that specific field during assignment.
This is Destructuring Assignment.
In this example below, the variables "name", "sex" and "age" in curly braces "{}" extract the values "John", "Male" and "24" from "data" respectively:
*The variable names in curly braces "{}" must be same as the key names in "data"
const data = { name: "John", sex: "Male", age: 24 };
const { name, sex, age } = data;
console.log(name); // John
console.log(sex); // Male
console.log(age); // 24
If the variable names in curly braces "{}" are not same as the key names in "data", the values of "undefined" are assigned:
const data = { name: "John", sex: "Male", age: 24 };
const { myName, mySex, age } = data;
console.log(myName); // undefined
console.log(mySex); // undefined
console.log(age); // 24
The order of the variables in curly braces "{}" doesn't matter:
const data = { name: "John", sex: "Male", age: 24 };
const { age, sex, name } = data;
console.log(name); // John
console.log(sex); // Male
console.log(age); // 24
You can rename the variables in curly braces "{}":
const data = { name: "John", sex: "Male", age: 24 };
const { name: firstName, sex: gender, age } = data;
console.log(firstName); // John
console.log(gender); // Male
console.log(age); // 24
After renaming the variables in curly braces "{}", the original variables don't work and give error:
const data = { name: "John", sex: "Male", age: 24 };
const { name: firstName, sex: gender, age } = data;
console.log(name);
console.log(sex);
console.log(age);
I want to be able to do this:
var user1 = {
name: 'John',
gender: 'male'
}
var user2 = {
name: 'James',
gender: 'male',
email: 'james#gmail.com'
}
user1.someSetMethod({email: 'john#gmail.com'});
user2.someSetMethod({name: 'Jenny', gender: 'female'});
Desired Outcome:
var user1 = {
name: 'John',
gender: 'male',
email: 'john#gmail.com'
}
var user2 = {
name: 'Jenny',
gender: 'female',
email: 'james#gmail.com'
}
I want a method that will set attributes according to what is passed into the function. Is the attribute doesn't exist I want it to be created, if it does, I want it to be overwritten.
Does a method like this exist in Javascript?
This is normally called extending your object. Virtually every JavaScript library has its own method to do this. Or you can write your own in a few lines of code.
jQuery extend
underscore.js extend
ExtJS extend
MooTools extend
Prototype extend
Using jQuery's method, you'd do it like so:
var user1 = {
name: 'John',
gender: 'male'
};
$.extend(user1, {
email: 'john#gmail.com'
});
user1.email === 'john#gmail.com'; //true
No, You don't want to do this.
The only way to add a method to all objects is to extend Object.prototype.
Doing so (in ES3 browsers like IE8) has a consequence of adding properties to enumerations.
For example:
Object.prototype.extend = function (o) {
// clone properties of o into this
};
var someObj = {};
for (var key in someObj) {
console.log(key); // "extend"
}
The best you can do is use Object.extend
Object.extend(user2, {
name: "Jenny",
gender: "female"
});
pd has an implementation of extend or you can use:
Object.extend = function (target, source) {
for (var key in source) {
target[key] = source[key];
}
};
If you are willing to use jquery, you can use it's extend method, along with some defaults that will make sure all of the properties you want are set correctly.
Something like this:
function whatever(obj1) {
var defaults = {
name: 'Foo Bar',
email: 'email#example.com',
gender: 'male'
};
return $.extend(defaults, obj1);
}