error in updating usehook object using spread operator - javascript

How to target a key when I have multiple alike keys in an object. If I try to target my desired key, it shows a syntax error.
const [modifiedNonFormData, setModifiedNonFormData] = useState({
"author": {
"lastName": "",
"location": {
"latitude": 49.3542671,
"longitude": 8.133071
},
"shippingAddress": {
"postalCode": "",
"name": "",
"address": "",
"location": {
"longitude": "",
"latitude": ""
},
"email": "",
"phone": "+14356234653"
},
"phone": "+14356234653",
"firstName": e.target.value
},})
const phoneHandler = (e) => {
let val = e.target.value
setModifiedNonFormData(modifiedNonFormData => {
return (
...modifiedNonFormData,
...modifiedNonFormData.author.phone:val
)
})}
I am trying to update/modify onChange input value

You need to do this instead:
setModifiedNonFormData(data => {
return ({
...data,
author: {
...data.author,
phone: val
}
})
})}
Explanation
You need to return a new object to a state setter in react. A common way to do this is through object destructuring. Let's say you have data and you want to clone it. You can do:
const newData = { ...data }
This would copy all of the values from data to a new object. This is also the reason why modifying data works - you are copying the values but also setting a new value for a property:
const newData = { ...data, newProperty: newValue }
However, this syntax is limited to replacing the value of a property. Therefore, if you want to modify the value of a property in an nested object, you have to also use the same syntax inside.

Related

angular and rxjs - removing properties from object

I have an endpoint that returns the following object properties:
{
"id": "1",
"department": "sample",
"address": "sample",
"email": "sample#email.com",
"products": [
{
"id": "100",
"product_type": "A",
"product_category": "sample",
"category": "sample"
},
{
"id": "101",
"product_type": "A",
"product_category": "sample",
"category": "sample"
}
]
}
I'm doing like this on Angular
this.httpService.get<Product>(<my_endpoint>).pipe(map(response => response.data))
I need to remove all the properties product_type from the array of objects and keep the rest intact. I can't find if is possible to do this with only RxJs library filtering capabilities.
You can use RxJS pluck and map, as well as array map and object destructuring to remove the un-needed property.
this.httpService.get<Product>(<my_endpoint>).pipe(
pluck('data'),
map( data => {
const products = data.products.map( p => {
const {product_type, ...others} = p;
return {
...others
}
});
return {
...data,
products
}
})
)
Note: don't use delete on objects if you can avoid it (it mutates the object)
Inside your map function do this:
map((response) =>{
let data = response.data;
let products = data.products;
products =products.map((product) =>{
delete product['property1'];
return product; // without deleted properties;
})
data.products =products ;
return data;
})

Filter array of nested object using javascript

I want to filter specific object using nested object element this
"token": "4f1f17f6503e4c5a3a269ecf93d6c92d"
This my data:
const data = [
{
name: "test",
token: {
expiryTime: "2021-09-24T12:27:30.654Z",
purpose: "ForgotPassword3",
token: "4f1f17f6503e4c5a3a269ecf93d6c92d",
},
user_id: "acaacc940c9ebfe798dee68acf5c",
zipcode: "",
},
{
name: "df ",
token: null,
user_id: "e0efe9810ca289ccd590bce48051",
zipcode: "",
},
{
name: "Io",
phone: "88888888",
state: "NY",
token: null,
user_id: "c88ce38d0c86f786c3a4b0f9f967",
zipcode: "13201",
},
];
Expected output is:
Data array inside the first object of token using filter object. Below given expected out.
const data = [
{
name: "test",
token: {
expiryTime: "2021-09-24T12:27:30.654Z",
purpose: "ForgotPassword3",
token: "4f1f17f6503e4c5a3a269ecf93d6c92d",
},
user_id: "acaacc940c9ebfe798dee68acf5c",
zipcode: "",
},
];
If you want a specific object, you could use find instead of filter. find will return the first element which verifies the condition specified to the find method where as the filter method is used to filters all the elements and returns all the element that matches the condition withing an array.
*You need to add the optional chaining ?. because the token object might be null like you have in some of your data
here both examples:
const data = [
{
"name": "test",
"token": {
"expiryTime": "2021-09-24T12:27:30.654Z",
"purpose": "ForgotPassword3",
"token": "4f1f17f6503e4c5a3a269ecf93d6c92d"
},
"user_id": "acaacc940c9ebfe798dee68acf5c",
"zipcode": ""
},
{
"name": "df ",
"token": null,
"user_id": "e0efe9810ca289ccd590bce48051",
"zipcode": ""
},
{
"name": "Io",
"phone": "88888888",
"state": "NY",
"token": null,
"user_id": "c88ce38d0c86f786c3a4b0f9f967",
"zipcode": "13201"
}
]
const resFilter = data.filter(x => x.token?.token === "4f1f17f6503e4c5a3a269ecf93d6c92d");
console.log(resFilter);
const resObj = data.find(x => x.token?.token === "4f1f17f6503e4c5a3a269ecf93d6c92d");
console.log(resObj);
You must use the following code
const finded = data.filter(user => user?.token?.token ==="value"})
console.log(finded);

Property assignment expected when using template literals to create an Object

I am trying to create an object inside a JSON object that will be later populated from FormData:
function toJSONstring(form) {
let object = {`"${form.name}": {}`}; //Property assignment expected.ts(1136)
let formData = new FormData(form);
formData.forEach((value, key) => {
// Reflect.has in favor of: object.hasOwnProperty(key)
if (!Reflect.has(object, key)) {
object[key] = value;
return;
}
if (!Array.isArray(object[key])) {
object[key] = [object[key]];
}
object[key].push(value);
});
form.reset();
return JSON.stringify(object);
}
What I want to obtain is the following JSON:
{
"network_settings": {
"connection": "wifi",
"type": "dhcp",
"ssid": "Jorj_2.4",
"ip_address": "",
"gateway": "",
"subnet": "",
"dns": ""
}
}
but I get Property assignment expected.ts(1136).
If I replace
let object = {`"${form.name}": {}`};
with let object = {}; then I get a normal JSON object:
{
"connection": "wifi",
"type": "dhcp",
"ssid": "Jorj_2.4",
"ip_address": "",
"gateway": "",
"subnet": "",
"dns": ""
}
How can I created the nested object that I want ?
For dynamic keys in script you have to enclose your expression inside []
const form = {
name: 'network_settings'
}
let obj = {[form.name]: {}};
console.log(obj);
Go back to what you had first:
let object = {};
And after you have populated the object, wrap it using computed property name syntax:
return JSON.stringify({ [form.name]: object });

how to insert object key into object value and turn it into an array?

what I have is like this
const employees = {
"0813562121": {
"city": "Melbourne",
"name": "Allison"
},
"8753452122": {
"city": "Melbourne",
"name": "Aria"
}
}
I need to make it into like this
const employees = [
{
"city": "Melbourne",
"name": "Allison",
"_id": "0813562121"
},
{
"city": "Melbourne",
"name": "Aria",
"_id": "8753452122"
}
]
i was thinking of using index of Object.keys(employees ) and Object.values(employees ), but I couldn't figure it out.
You're on the right track with Object.values, but I'd use Object.entries since it gives you both the property name and its value. Then it's a map:
const result = Object.entries(employees).map(([name, value]) => ({...value, _id: name}));
Live Example:
const employees = {
"0813562121": {
"city": "Melbourne",
"name": "Allison"
},
"8753452122": {
"city": "Melbourne",
"name": "Aria"
}
};
const result = Object.entries(employees).map(([name, value]) => ({...value, _id: name}));
console.log(result);
That uses:
Object.entries to get an array of [name, value] pairs from the object.
map to map the entries of that array into a different format
A concise-form arrow function for the map callback (more in a moment).
Destructuring in the map callback's parameter list to get the name and value in named parameters.
Spread syntax inside an object literal to spread out the own, enumerable properties of the objects into a new object, adding the _id property
Alternatively, you could modify the object rather than creating a new one, so that non-enumerable, or non-own properties are retained:
const result = Object.entries(employees).map(([name, value]) => {
value._id = name;
return value;
});
Live Example:
const employees = {
"0813562121": {
"city": "Melbourne",
"name": "Allison"
},
"8753452122": {
"city": "Melbourne",
"name": "Aria"
}
};
const result = Object.entries(employees).map(([name, value]) => {
value._id = name;
return value;
});
console.log(result);
The key thing there is that the same objects are in both employees and result, whereas with the first one we make a shallow copy.
try this
const employees = {
"0813562121": {
"city": "Melbourne",
"name": "Allison"
},
"8753452122": {
"city": "Melbourne",
"name": "Aria"
}
}
let jsonVariants =[];
Object.keys(employees).forEach(function(key) {
let obj =employees[key];
obj["_id"] =key;
jsonVariants.push(obj);
});
console.log(jsonVariants);

Iterate through the child objects and get all the values with javascript

var formmd = {
"frmType": "Registration",
"frmStage": "step1-complete",
"formattr": {
"SystemUser": {
"LoginName": "A#test.com",
"Password": "password",
"PIN": "",
"IsTestUser": false
},
"ConsumerAddress": {
"AddressLine1": "201 MOUNT Road",
"AddressLine2": null,
"AddressTypeId": "1",
"City": "OLA TRAP",
"State": "NM",
"Zipcode": "60005"
},
"ConsumerPhone": {
"PhoneTypeId": 6,
"PhoneNumber": "9876543210",
"PrimaryPhoneIndicator": null,
"AllowVoicemail": false
},
"PhysicianSpecialty": {
"SpecialtyList": [
"1",
"2"
]
},
}
}
I'm trying to fetch all the values of the child objects under formattr but I'm unable to iterate inside the child objects. The following is the script I tried.
My Result should be
"A#test.com"
"password"
"PIN": ""
False
201 MOUNT Road"
The script I tried is
function walk(formmd) {
var obj1 = formmd.formattr;
for(var key in obj1){
if (obj1.hasOwnProperty(key)) {
var val1 = obj1[key];
if(val1.hasOwnProperty(key)){
for(var key in val1){
var val2 =val1[key];
console.log("val2");
}
}
}
}
}
How to access the keys of child objects in an automated way?
Try like this
for (var key in formmd) {
var val1 = formmd[key];
if (key=="formattr") {
for (var key1 in val1) {
var val2 = val1[key1];
for(var key2 in val2)
console.log(val2[key2]);
}
}
}
DEMO
You might find it easier to understand code written in a functional style. This is one solution, which I'll explain:
Object.values(formmd.formattr)
.map(obj => Object.values(obj))
.reduce((acc, vals) => acc.concat(vals), [])
The first expression Object.values(formmd.formattr) gives you an array of all the values (not keys) under formmd.formattr. Something like:
[{"LoginName": "A#test.com", "Password": "password", …}, {"AddressLine1": "201 MOUNT Road", "AddressLine2": null, …}, …]
Since you want the values within each of these sub-objects the next line .map(obj => Object.values(obj)) will do just that. It returns a new array where each object in the input array is transformed through Object.values(…). It returns something like:
[["A#test.com", "password", "", false], ["201 MOUNT Road", null, "1", …], …]
This array has all the data you're after, but in nested arrays, so it needs to be flattened with .reduce((acc, vals) => acc.concat(vals), []). This reduce will successively concat these sub-arrays to produce a single array like:
["A#test.com", "password", "", false, "201 MOUNT Road", null, "1", …]
which contains all the values of the child objects under formattr.
Here's some other ways to do it:
Object.values(formmd.formattr)
.reduce((acc, x) => acc.concat(Object.values(x)), [])
or
[].concat(...
Object.values(formmd.formattr)
.map(obj => Object.values(obj)))
You will have to use Object.entries()
The Object.entries() method returns an array of a given object's own
enumerable string-keyed property [key, value] pairs, in the same order
as that provided by a for...in loop. (The only important difference is
that a for...in loop enumerates properties in the prototype chain as
well).
Example -
for (const [key, value] of Object.entries(objectName)) {
console.log(`${key}: ${value}`);
}
Code Snippet -
var formmd = {
"frmType": "Registration",
"frmStage": "step1-complete",
"formattr": {
"SystemUser": {
"LoginName": "A#test.com",
"Password": "password",
"PIN": "",
"IsTestUser": false
},
"ConsumerAddress": {
"AddressLine1": "201 MOUNT Road",
"AddressLine2": null,
"AddressTypeId": "1",
"City": "OLA TRAP",
"State": "NM",
"Zipcode": "60005"
},
"ConsumerPhone": {
"PhoneTypeId": 6,
"PhoneNumber": "9876543210",
"PrimaryPhoneIndicator": null,
"AllowVoicemail": false
},
"PhysicianSpecialty": {
"SpecialtyList": [
"1",
"2"
]
},
}
}
for (const [key, value] of Object.entries(formmd.formattr)) {
console.log('Value',value);
}

Categories

Resources