I'm using the following code to get object from react state.
const { organizations } = this.state;
The sate object is as following.
this.state = {
userOrganizations: {},
OrganizationUsers: {}
}
userOrganizations is actually an object with an inner object named organizations. How can I map this using es6 code?
Edit
What I actually need is to get inner objects of both the userOrganizations and OrganizationUsers using the following code.
const { organizations, users } = this.state;
The organizations and users are sub objects which are inside the userOrganizations and OrganizationUsers.
So when I want to handle them, will they work with just calling
const { organizations, users } = this.state.userOrganizations, this.state.OrganizationUsers;
You can nest destructruring like
const { userOrganizations : { organizations } } = this.state;
or simply write
const { organizations } = this.state.userOrganizations;
This is so simple but still many got it wrong. Here is an example of inner destructuring
const obj = {
someArray: [ 1, 2, 3],
someInnerObj : {num: 123, txt: 'text'}
}
const {someArray: [first,second], someInnerObj: { num: myNum, txt: meText}} = obj
console.log(first,second,myNum,meText)
Try it in console
Just use dot notation until you get to the parent object just above the property you want
const obj = { outer: { inner: 'value' }};
const { inner } = obj.outer;
console.log(inner);
To destructure more than one thing at a time in different nested levels, try something like:
const x = {
state: {
userOrganizations: {
organizations: 'orgValue'
},
OrganizationUsers: {
users: 'userValue'
}
}
}
const { userOrganizations: { organizations }, OrganizationUsers: { users } } = x.state;
console.log(organizations + ' ' + users);
If i'am not wrong this should solve your issue,
const { organizations } = this.state.userOrganizations;
Related
I have a performance issue with NgRx, I have an array with thousands of objects that looks like this (I can't change that structure even I don't like it):
state.alarms structure:
[
{ global: {...} },
{ 282: {...} },
{ 290: {...} },
{ 401: {...} }
etc...
]
addNewAlarm(state, alarm) here alarm object is for example:
{ 282: {...} }
As you can see the object looks something like this { someNumber: nestedObjectForThatNumber }
I'm listening for changes and if some appear I have to replace object where "the key" is given number.
In the case from the screenshot for example I get { 282: {x: 1, y: 2, z: 3} } so I have to replace the item of array with index 1.
In my reducer I've created something like this but it doesn't work as I expected:
export function addNewAlarm(state: State, alarm: AlarmsObject): State | undefined {
const alarms: AlarmsObject[] = [...state.alarms];
if (state) {
const existingRecord = state.alarms.find(alarm1 => alarm1.hasOwnProperty(Object.keys(alarm)[0]));
if (existingRecord) {
const index = state.alarms.indexOf(existingRecord);
alarms[index] = alarm;
}
}
return { ...state, alarms };
}
Maybe someone can give me a hint how to do it in a right way?
you can use findIndex (If not found return -1) but, why not create an object?
stateObj: any = {};
this.state.forEach((x) => {
this.stateObj = { ...this.stateObj, ...x };
});
So you only need use
//Note you needn't return anything
addNewAlarm(stateObj: any, alarm: AlarmsObject){
const key=Object.keys(alarm)[0]
this.stateObj[key]=this.alarm[key]
}
A fool stackblitz
here is by JS code:
var a = { depth: object_with_many_attributes.depth };
notice how depth appear twice, any standard way to rewrite by using depth just once?
You can use Object Destructuring, but in that case, you need to define additional variables, like in an example
const object_with_many_attributes = { depth: 'xxx', 'somethingOther': 'qwerty'};
const { depth, somethingOther } = object_with_many_attributes;
const a = { depth, somethingOther };
If depth must be used only once, you can destructure it with key:
// assignment
var object_with_many_attributes = { depth: 'foo', bar: 123 };
// destructure it:
var { 'depth' : a } = object_with_many_attributes;
console.log('object a:', { a }); // use as object later
I need to get the value of roles in the following example.
const obj ={
id: 1,
"website.com": {
roles: ["SuperUser"]
}
}
const r = obj.hasOwnProperty("roles")
console.log(r)
Its parent objects name ("website.com") can change everytime as Im requesting it from the db. What is the best way to get this variable?
The obj would also be relatively large I just didnt include it in the example.
You could iterate over the object and exclude id. Example:
for (var x in obj) {
if (x !== 'id') {
console.log(obj[x].roles)
}
}
EDIT (to address your question edit):
If the root object has many keys, it would probably make sense to instead either move the domain from a key to a value (for example, domain: 'website.com' and move the roles up (flattening the object); or you could check for a key that looks like a domain using a regex. Example: if (/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.test(x) rather than if (x !== 'id'). The regex way would probably be brittle.
EDIT 2:
You could use the hasOwnProperty check like this:
let roles
for (let x in obj) {
if (obj[x].hasOwnProperty(roles)) {
roles = obj[x])
}
}
You can get the roles by destructuring the roles property from the value of obj['website.com'].
If you want to do this dynamically, you will need to figure out key has a corresponding object with the property roles. Once you find all valid candidates, you can access the first (or whichever one you want) and then grab its value.
const hasRoles = obj => Object.entries(obj)
.filter(([key, value]) =>
value.hasOwnProperty('roles'));
const obj = {
id: 1,
"website.com": {
roles: ["SuperUser"]
}
}
const [ first ] = hasRoles(obj);
const [ website, { roles } ] = first;
console.log(`website = ${website} | roles = ${roles}`);
Alternatively, for a greedy match:
const hasRolesGreedy = obj => Object.entries(obj)
.find(([key, value]) =>
value.hasOwnProperty('roles'));
const obj = {
id: 1,
"website.com": {
roles: ["SuperUser"]
}
}
const found = hasRolesGreedy(obj);
const [ website, { roles } ] = found;
console.log(`website = ${website} | roles = ${roles}`);
only access to the nested key like this:
let roles = obj["website.com"].roles;
console.log(roles);
That way, you will get an array, then you can iterate or get a value by the index.
Since you don't know what the name is, you need to iterate over all properties and find the first with the roles property:
const testObj ={
id: 1,
"website.com": {
roles: ["SuperUser"]
}
}
const testObj2 = {
id: 2,
"anotherwebsite.com":{
roles: ["AnotherSuperUser"]
}
}
function getRoles(obj){
for(let x in obj){
if(Object.prototype.hasOwnProperty.call(obj, x))
{
if(obj[x].roles){
return obj[x].roles;
}
}
}
return undefined;
}
console.log(getRoles(testObj));
console.log(getRoles(testObj2));
I need to destructure a nested object. what is the best way to avoid exceptions when some of the nested properties are missing, while assigning those who do exist?
const data = {
title: 'hello',
// nest: {
// road: 5
// }
};
const { title, nest: { road = '' } } = data;
console.log(road);
/** i want it to return '' or undefined.
* actually it returns: Cannot match against 'undefined' or 'null'
*
*/
console.log(title)
/** i want it to return 'hello'
* actually: never got there as there was an exception.
*/
You can assign in a parent object level to empty object (or with value) even if it has further nested object destruction:
const { title, nest: { road = '<default road>' } = {} } = data;
const data = {
title: 'hello',
//nest: {
// road: 5
//}
};
const { title, nest: { road = '<default road>' } = {} } = data;
console.log(title);
console.log(road);
And also, you are doing it wrong, if you are destructing using
{title: englishTitle} = {title: 1234}
then, you should use englishTitle to get the value 1234, and not title, or use
{title} = {title: 1234}
and use title to get 1234
I am getting the Response from the server like this
{
owners:[
{
_id:"33333"
email:test1#gmail.com
}
{
_id:"1111"
email:test2#gmail.com
}]
employee:[
{
_id:"44342"
email:test1#gmail.com
}
{
_id:"35345"
email:test3#gmail.com
}
{
_id:"3556"
email:test4#gmail.com
}
]
users:[
{
_id:"56744"
email:test5#gmail.com
}
{
_id:"8908"
email:test4#gmail.com
}]
}
i want keep the objects Which are only having unique email id in all the array of objects the Result should be like this:
{
owners:[
{
_id:"33333"
email:test1#gmail.com
}
{
_id:"1111"
email:test2#gmail.com
}]
employee:[
{
_id:"35345"
email:test3#gmail.com
}
{
_id:"35345"
email:test4#gmail.com
}
]
users:[
{
_id:"56744"
email:test5#gmail.com
}
]
}
can anybody help me on this Please.
Since you want uniqueness across two array, you have to combine them first.
let combined = result.owners.map(o => {o.type = 'owner'; return o;})
.concat(result.users.map(u => {u.type = 'user'; return u;});
combined = _.uniqBy(combined, 'email');
result.owners = _.filter(combined, {type: 'owner');
result.users = _.filter(combined, {type: 'user');
same thing with employees.
Well there are a few ways of doing this. One of the easiest would be using libraries like lodash or underscore and using the uniq method to filter out duplicate objects on the basis of a property.
Using underscore as an example to get a unique list of owner objects:
_.uniq(owners, 'email')
Or a function of this sort would also work:
function uniqeValues(objects, property) {
let unique_values = {};
objects.forEach(object=> {
if (!unique_values.hasOwnProperty(object[property])) {
unique_values[object[property]] = object;
}
});
return Object.values(unique_values);
}