Javascript - Assign object item with values from another object - javascript

I have an object with few items and I want to update the values of one property options from another object.
Object 1 :
structure = [
{
id: 'name',
label: 'Name',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'address',
label: 'Address',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'phone',
label: 'Phone',
filterType: 'select',
filterOn: 'contains',
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
if the id is phone then I want to get the values from the object 2 phoneList and assign it to the options instead of hard coding it.
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
object 2 is
this.props.phoneList = [{name: 'aaa', age: 11},{name : 'bbb' , age : 12}, and so on
]
label and values will be this.props.phoneList[i].name
how to loop over this and get the latest values from the other object

First use filter to identify the object with id phone. Then use map to transform this.probs.phoneList in the desired format and assign to options.
structure.filter (x => x.id == 'phone')[0].options = this.probs.phoneList.map (x => ({label: x.name, value: x.name}));

Related

Javascript array of objects merge based on the object property [duplicate]

This question already has answers here:
Group array items using object
(19 answers)
Closed 2 years ago.
I have an array below.
var array = [
{ category: 'Input', field: 0, value: '17' },
{ category: 'Input', field: 0, value: '5' },
{ category: 'Input', field: 0, value: '8' },
{ category: 'Input', field: 5, value: '1' },
{ category: 'Input', field: 5, value: '4' },
{ category: 'Input', field: 0, value: '1' }
];
I want to convert the array-like below -- merge the objects based on the field value, if the value is same and get the result like below
[
{ category: 'Input', field: 0, value: ['17', '5', '8', '1'] },
{ category: 'Input', field: 5, value: ['1', '4'] }
];
var array = [
{ category: 'Input', field: 0, value: '17' },
{ category: 'Input', field: 0, value: '5' },
{ category: 'Input', field: 0, value: '8' },
{ category: 'Input', field: 5, value: '1' },
{ category: 'Input', field: 5, value: '4' },
{ category: 'Input', field: 0, value: '1' }
];
const obj = array.reduce((val, cur) => {
if (val[cur.field]) {
val[cur.field].push(cur.value);
} else {
val[cur.field] = [cur.value];
}
return val;
}, {});
const res = Object.keys(obj).map(key => ({
category: 'Input',
field: parseInt(key),
value: obj[key]
}));
console.log(res);

Create array of object with condition

I am creating array of object. I want to add object based on condition. But, It add false instead of not adding object in array.
I tried:
const flag = false;
const list = [
{ key: 'abc', label: 'abcd' },
flag && { key: 'bbb', label: 'abcd' },
{ key: 'ccc', label: 'abcd' },
flag && { key: 'ddd', label: 'abcd' },
{ key: 'eee', label: 'abcd' },
];
console.log(list);
You can check output there are false in array.
Assuming that all elements that are to be kept in the array do not have falsey values, you could simply filter them based on the value afterwards like so:
const flag = false;
const list = [
{ key: 'abc', label: 'abcd' },
flag && { key: 'bbb', label: 'abcd' },
{ key: 'ccc', label: 'abcd' },
flag && { key: 'ddd', label: 'abcd' },
{ key: 'eee', label: 'abcd' }
].filter(Boolean);
console.log("list:", list);
const flag2 = true;
const list2 = [
{ key: 'abc', label: 'abcd' },
flag2 && { key: 'bbb', label: 'abcd' },
{ key: 'ccc', label: 'abcd' },
flag2 && { key: 'ddd', label: 'abcd' },
{ key: 'eee', label: 'abcd' }
].filter(Boolean);
console.log("list2:", list2);
To do it all in a single statement, you can use the spread operator:
const list = [
{ key: 'abc', label: 'abcd' },
...(flag ? [{ key: 'bbb', label: 'abcd' }] : []),
{ key: 'ccc', label: 'abcd' },
...(flag ? [{ key: 'ddd', label: 'abcd' }] : []),
{ key: 'eee', label: 'abcd' },
];
It's pretty ugly though.

Typescript Interface Definition dynamic

I am trying to define an interface for the following data:
result =
{
"data1" : [ { "type1" : 30 }, { "type2" :40 } ],
"data1" : [ { "abc" : 40 }, { "def" 940 } ],
"data3" : []
}
here the keys and values inside result object are dynamic. Even the values inside array of objects are dynamic but it will be of format string: number or that array can be empty just as in data3.
I tried using [x:any]: any, but looks like it will remove the significance of rest of the types defined in interface as it will match eveything.
Can someone help me here?
You can define dynamic key interface as follows:
interface Result {
[key: string]: {
[childKey: string]: number;
}[];
}
Something similar you can do -->
You don't need to use an indexer (since it a bit less typesafe). You have two options :
interface EnumServiceItem {
id: int; label: string; key: any
}
interface EnumServiceItems extends Array<EnumServiceItem>{}
// Option A
var result: EnumServiceItem[] = [
{ id: 0, label: 'CId', key: 'contentId' },
{ id: 1, label: 'Modified By', key: 'modifiedBy' },
{ id: 2, label: 'Modified Date', key: 'modified' },
{ id: 3, label: 'Status', key: 'contentStatusId' },
{ id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
{ id: 5, label: 'Title', key: 'title' },
{ id: 6, label: 'Type', key: 'contentTypeId' },
{ id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
];
// Option B
var result: EnumServiceItems = [
{ id: 0, label: 'CId', key: 'contentId' },
{ id: 1, label: 'Modified By', key: 'modifiedBy' },
{ id: 2, label: 'Modified Date', key: 'modified' },
{ id: 3, label: 'Status', key: 'contentStatusId' },
{ id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
{ id: 5, label: 'Title', key: 'title' },
{ id: 6, label: 'Type', key: 'contentTypeId' },
{ id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
]
Personally I recommend Option A (simpler migration when you are using classes not interfaces).

Set Value in Select Option of dynamic form

I have created dynamic form, in that form there is one dropdown. In that dropdown I want to have fiscal week for that I want to run loop inside ts function.
form.ts -
<div class="col-md-9" [ngSwitch]="field.type">
<dropdown *ngSwitchCase="'dropdown'" [field]="field" [form]="form"></dropdown>
</div>
dropdown.ts -
public field: any[] = [
{
type: 'dropdown',
name: 'fiscalweek',
label: 'fiscalweek',
placeholder: 'Fiscal Week',
required: true,
options: this.getWeek()
}
];
getWeek(){
this.week =
[
{ key: 'Select', label: 'ALL'},
{ key: '1', label: '1'},
{ key: '2', label: '2'},
{ key: '3', label: '3'},
{ key: '4', label: '4'},
{ key: '5', label: '5'},
{ key: '6', label: '6'},
.
.
.
{ key: '53', label: '53'}
]
;
return this.week;
}
I want to run a loop inside this getWeek from 1 to 53 instead of hardcoding.
Can someone please suggest me how to do that ?
You can populate week array by a simple for loop
Try like this:
Working Demo
getWeek() {
this.week = [];
this.week.push({ key: "Select", label: "ALL" });
for (var i = 1; i <= 53; i++) {
this.week.push({ key: i.toString(), label: i.toString() });
}
return this.week;
}

Clone array of object removes class type

I have to deep clone an array of objects
filterList: Filter[] = [
new ChipsFilter('Rating', 'rating',
[
{
name: '5 ★',
key: '5',
value: true
},
{
name: '4 ★',
key: '4',
value: true
},
{
name: '3 ★',
key: '3',
value: true
},
{
name: '2 ★',
key: '2',
value: true
},
{
name: '1 ★',
key: '1',
value: true
}
]),
new CheckboxFilter('Country', 'country', [
{
name: 'India',
key: 'india',
value: true
},
{
name: 'Brazil',
key: 'brazil',
value: false
},
{
name: 'UAE',
key: 'uae',
value: true
},
{
name: 'Sri Lanka',
key: 'sri-lanka',
value: true
},
{
name: 'USA',
key: 'usa',
value: false
},
{
name: 'England',
key: 'england',
value: true
},
{
name: 'South Africa',
key: 'south-africa',
value: true
}
]),
new CalendarFilter('Date', 'createdAt', [
{
name: 'Start Date',
key: 'startDate',
value: ''
},
{
name: 'End Date',
key: 'endDate',
value: ''
}
]),
];
After clone I want the data type of objects to be same but I get the object as the type instead, have tried below methods for cloning.
Using JSON stringify
this.filterList = this.filterList.map(a => Object.assign({}, a));
Using object.assign
this.filterList = this.filterList.map(a => Object.assign({}, a));
The first argument to Object.assign() is the target object. That object effectively is the result. What Object.assign() does is just copy over own enumerable properties of your CalendarFilter instances to that target.
What you could do instead is create new instances of your objects in array.map() instead of assigning them to a generic object with Object.assign().
this.filterList = this.filterList.map(a => new CalendarFilter(...))
Of course, you need to use the right constructor for each type you encounter in your array.
This will take into account the variable Object types:
class ChipsFilter {constructor(){this.chipsProp="chipsProp"}}
class CheckboxFilter {constructor(){this.checkboxProp= "checkboxProp"}}
class CalendarFilter {constructor(){this.calendarProp= "calendarProp"}}
const filterList = [
new ChipsFilter(),
new CheckboxFilter(),
new CalendarFilter(),
];
let out = filterList.map(obj=>Object.assign(new obj.constructor, obj));
console.log(out[0].constructor, out[0]);
console.log(out[1].constructor, out[1]);
console.log(out[2].constructor, out[2]);

Categories