Access Array from Property in Nested Object - arrays

I have the following nested object:
export const mockData = {
sections: [
{
name: 'Client',
subSections: [
{
name: 'Client Detail'
}
]
},
{
name: 'Sales',
subSections: [
{
name: 'Overview',
subSections: [
{
name: 'Overview - A',
fields: [
{
key: 'firmName',
type: 'input',
templateOptions: {
label: 'Firm Name',
required: true
}
},
{
key: 'requestOption',
type: 'select',
templateOptions: {
label: 'Request Option',
required: true,
options: [
{ value: '1', label: '1' },
{ value: '2', label: '2' },
{ value: '3', label: '3' },
{ value: '4', label: '4' }
]
}
},
{
key: 'region',
type: 'select',
templateOptions: {
label: 'Region',
required: true,
options: [
{ value: '1', label: '1' },
{ value: '2', label: '2' },
{ value: '3', label: '3' },
{ value: '4', label: '4' },
{ value: '5', label: '5' }
]
}
}
]
}
]
}
]
}
]
};
and I would like to access the array from the fields property in order to render a form. Right now what I have is overviewA: FormlyFieldConfig[] = mockData.sections[1].subSections[0].subSections[0].fields, but I am facing the error of
Property 'subSections' does not exist on type '{ name: string; }'.
However, this error goes away when do a work-around and I add the property subSections to the nested object like so:
export const mockData = {
sections: [
{
name: 'Client',
subSections: [
{
name: 'Client Detail',
subSections: []
}
]
},
{
name: 'Sales',
subSections: [
{
name: 'Overview',
subSections: [
{
name: 'Overview - A', ...
I was wondering why
I was facing the issue without the work-around, and
How can I access the array from the property fields without the work-around?

Related

How to return the object if no value found otherwise do some looping with condition and return object using react and typescript?

Hi i have an array of objects like below,
const arr_obj = [
{
id: '1',
jobs: [
{
completed: false,
id: '11',
run: {
id: '6',
type: 'type1',
},
},
{
completed: true,
id: '14',
run: {
id: '17',
type: 'type1',
},
},
{
completed: false,
id: '12',
run: {
id: '7',
type: 'type2',
},
},
],
},
{
id: '2',
jobs: [
{
completed: true,
id: '13',
run: {
id: '8',
type: 'type2',
},
},
{
completed: true,
id: '16',
run: {
id: '9',
type: 'type1',
},
},
{
completed: true,
id: '61',
run: {
id: '19',
type: 'type1',
},
},
],
},
{
id: '3',
jobs: [
{
completed: false,
id:'111',
run: {
id: '62',
type: 'type1',
},
},
],
},
],
Now i have to get ids from arr_obj which matches this arr of ids
const arr_ids = ["1","2"]
and whose runs are of type "type1" and none of the jobs have completed: false
so the expected output is "2"
the below code works,
const filtered_arr_obj = arr_obj.filter(obj => {
if (arr_ids.includes(obj.id)) {
const jobs = obj.jobs.filter(job => job.run.type === "type1");
if (jobs.length > 0) {
return jobs.every(job => job.completed === true);
}
return false;
}
return false;
});
let filtered_ids = filtered_arr_obj.map(obj => obj.id);
console.log("filteredIds", filteredIds) //2
Now the problem is if there are no run and run of type "type" for job then i want to also filter the object which has no job run of type "type1"
so consider below example
const arr_obj = [
{
id: '1',
jobs: [
{
completed: false,
id: '11',
run: {
id: '6',
type: 'type1',
},
},
{
completed: true,
id: '14',
run: {
id: '17',
type: 'type1',
},
},
{
completed: false,
id: '12',
run: {
id: '7',
type: 'type2',
},
},
],
},
{
id: '2',
jobs: [
{
completed: true,
id: '13',
run: {
id: '8',
type: 'type2',
},
},
{
completed: true,
id: '16',
run: {
id: '9',
type: 'type1',
},
},
],
},
{
id: '3',
jobs: [
{
completed: false,
id: '111',
run: {
id: '62',
type: 'type1',
},
},
],
},
{
id: '4',
jobs: [
{
completed: true,
id: '121',
run: {
id: '66',
type: 'type2',
},
},
],
},
],
and
arr_ids = ["1", "2", "4"]
so the expected output is
["2", "4"]
here 4 is also selected because arr_ids has "4" and the object in arr_obj with id "4" has no job run with type "type1".
how can I modify the above code snippet to also include this condition? could someone help me with this? thanks.
I am new to programming and please do answer the question.
It Looks like when the id is present in the arr_ids and if the jobs length is <= 1 then we should filter it , else we are filtering the type1 jobs and checking whether all are completed .
const arr_obj = [
{
id: '1',
jobs: [
{
completed: false,
id: '11',
run: {
id: '6',
type: 'type1',
},
},
{
completed: true,
id: '14',
run: {
id: '17',
type: 'type1',
},
},
{
completed: false,
id: '12',
run: {
id: '7',
type: 'type2',
},
},
],
},
{
id: '2',
jobs: [
{
completed: true,
id: '13',
run: {
id: '8',
type: 'type2',
},
},
{
completed: true,
id: '16',
run: {
id: '9',
type: 'type1',
},
},
{
completed: true,
id: '61',
run: {
id: '19',
type: 'type1',
},
},
],
},
{
id: '3',
jobs: [
{
completed: false,
id:'111',
run: {
id: '62',
type: 'type1',
},
},
],
},
{
id: '4',
jobs: [
{
completed: true,
id: '121',
run: {
id: '66',
type: 'type2',
},
},
],
},
];
const arr_ids = ["1", "2", "4"];
const filtered_arr_obj = arr_obj.filter(obj => {
if (arr_ids.includes(obj.id)) {
if(obj.jobs.length <= 1 ){
return true;
}
else {
const type1jobs = obj.jobs.filter(job => job.run.type === "type1");
return type1jobs.every(job => job.completed );
}
}
return false;
});
let filtered_ids = filtered_arr_obj.map(obj => obj.id);
console.log("filteredIds", filtered_ids)

Antd tree table grouped by column value

I need to implement tree table in my react application. that has grouped by an object property value.
The object is as follows
{
"SP": [
{
"DisplayName": "audi",
"Name": "r8",
"Type": "2012"
},
{
"DisplayName": "audi",
"Name": "rs5",
"Type": "2013"
}
],
"Code": [
{
"DisplayName": "ford",
"Name": "mustang",
"Type": "2012"
},
{
"DisplayName": "ford",
"Name": "fusion",
"Type": "2015"
}
],
"Message": [
{
"DisplayName": "kia",
"Name": "optima",
"Type": "2012"
}
]
}
And my table should be as the following image
I have used antd in my project and I tried to implement this functionality with antd table and could not implement as I want. I need the filter functionality too.
Can anyone suggest a solution
You need to restructure your dataSource witch children prop:
function NestedTables() {
return (
<Flexbox>
<Table
size="small"
indentSize={0}
columns={columns}
dataSource={source}
/>
</Flexbox>
);
}
When your source is:
const source = [
{
key: '1',
Code: 'SP',
children: [
{
key: '11',
Code: '5001',
DisplayName: 'audi',
Name: 'r8',
Type: '2012'
},
{
key: '12',
Code: '313',
DisplayName: 'audi',
Name: 'rs5',
Type: '2013'
}
]
},
{
key: '2',
Code: 'Code',
children: [
{
key: '21',
Code: '243',
DisplayName: 'ford',
Name: 'mustang',
Type: '2012'
},
{
key: '22',
Code: '503431',
DisplayName: 'ford',
Name: 'fusion',
Type: '2015'
}
]
},
{
key: '3',
Code: 'Message',
children: [
{
key: '31',
Code: '4311',
DisplayName: 'kia',
Name: 'optima',
Type: '2012'
}
]
}
];
And defined columns filters:
const columns = [
{
title: 'Code',
dataIndex: 'Code',
key: 'Code',
filters: [
{ text: 'SP', value: 'SP' },
{ text: 'Code', value: 'Code' },
{ text: 'Message', value: 'Message' }
],
onFilter: (value, record) => record.Code.indexOf(value) === 0
},
{
title: 'Display Name',
dataIndex: 'DisplayName',
key: 'DisplayName',
filters: [
{ text: 'audi', value: 'audi' },
{ text: 'ford', value: 'ford' },
{ text: 'kia', value: 'kia' }
],
onFilter: (value, record) =>
record.children.filter(child => child.DisplayName === value).length > 0
},
{ title: 'Name', dataIndex: 'Name', key: 'Name' },
{ title: 'Type', dataIndex: 'Type', key: 'Type' }
];
Demo:

Get the array of values from array of objects using lodash

I have this array
this.complementaryFields = [
{
fieldName: 'complementaryLaser',
label: 'Laser Hair Removal'
},
{
fieldName: 'complementarySkin',
label: 'Skin'
},
{
fieldName: 'complementaryInjection',
label: 'Cosmetic Injections'
},
{
fieldName: 'complementaryNotSure',
label: 'Not Sure'
}
];
and I would like to create a new array out of it as below:
this.complementaryFieldNames = [
'complementaryLaser',
'complementarySkin',
'complementaryInjection',
'complementaryNotSure'
];
How would you do it using lodash?
You can simply use lodash _.map to get that result:
const data = [{ fieldName: 'complementaryLaser', label: 'Laser Hair Removal' }, { fieldName: 'complementarySkin', label: 'Skin' }, { fieldName: 'complementaryInjection', label: 'Cosmetic Injections' }, { fieldName: 'complementaryNotSure', label: 'Not Sure' } ];
const result = _.map(data, 'fieldName')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
With ES6 you can do same with Array.map and destructuring:
const data = [{ fieldName: 'complementaryLaser', label: 'Laser Hair Removal' }, { fieldName: 'complementarySkin', label: 'Skin' }, { fieldName: 'complementaryInjection', label: 'Cosmetic Injections' }, { fieldName: 'complementaryNotSure', label: 'Not Sure' } ];
const result = data.map(({fieldName}) => fieldName)
console.log(result)

Javascript arrays: How to remove the all matched elements which are contained in another array

I have 2 javascript arrays which are a, b and I want to remove the common elements from the array a.
Can you please help on this.
var a = [{
name: 'java',
id: '1'
},
{
name: 'php',
id: '2'
},
{
name: 'ruby',
id: '3'
},
{
name: 'phyton',
id: '4'
}
];
var b = [{
name: 'java',
id: '1'
},
{
name: 'php',
id: '2'
}
];
It's basically a simple filter operation. I'd take the ids from b into an array, then filter by those elements
var a = [{
name: 'java',
id: '1'
},
{
name: 'php',
id: '2'
},
{
name: 'ruby',
id: '3'
},
{
name: 'phyton',
id: '4'
}
];
var b = [{
name: 'java',
id: '1'
},
{
name: 'php',
id: '2'
}
];
const exists = b.map(e => e.id);
const res = a.filter(e => !exists.includes(e.id));
console.log(res);

ng-change blanking out dropdown

I have this drop down setup like this:
<div class="col-sm-2">
<select class="form-control" name="dataType" id="dataType"
ng-model="dataTypes"
ng-change="typeCheck()">
<option ng-repeat="option in dataTypes" value="{{option.id}}">{{option.name}}</option>
</select>
</div>
In my controller I have this function:
$scope.typeCheck = function () {
alert($scope.dataTypes);
};
After this function is called, sometimes my list disappears! I say sometimes as because it is only on certain elements that get called.
This is my array that gets loaded into the dropdown:
$scope.typeArrays = function () {
var vm = this;
vm.dataTypes = [];
vm.dataTypes = [
{ id: 'bigint', name: 'bigint' },
{ id: 'binary', name: 'binary' },
{ id: 'bit', name: 'bit' },
{ id: 'char', name: 'char' },
{ id: 'date', name: 'date' },
{ id: 'datetime', name: 'datetime' },
{ id: 'datetime2', name: 'datetime2' },
{ id: 'datetimeoffset', name: 'datetimeoffset' },
{ id: 'decimal', name: 'decimal' },
{ id: 'float', name: 'float' },
{ id: 'image', name: 'image' },
{ id: 'int', name: 'int' },
{ id: 'money', name: 'money' },
{ id: 'nchar', name: 'nchar' },
{ id: 'ntext', name: 'ntext' },
{ id: 'numeric', name: 'numeric' },
{ id: 'nvarchar', name: 'nvarchar' },
{ id: 'real', name: 'real' },
{ id: 'smalldatetime', name: 'smalldatetime' },
{ id: 'datetimeoffset', name: 'datetimeoffset' },
{ id: 'smallint', name: 'smallint' },
{ id: 'smallmoney', name: 'smallmoney' },
{ id: 'sql_variant', name: 'sql_variant' },
{ id: 'text', name: 'text' },
{ id: 'time', name: 'time' },
{ id: 'tinyint', name: 'tinyint' },
{ id: 'uniqueidentifier', name: 'uniqueidentifier' },
{ id: 'varbinary', name: 'varbinary' },
{ id: 'varchar', name: 'varchar' }
];
}
Here is a fiddle of my code.
You were pretty close, there was a little misconception about the models but this way, you set a dataType using ng-model and ng-change alerts the chosen dataType.
$scope.dataType = null;
$scope.dataTypes = [
{ id: 'bigint', name: 'bigint' },
{ id: 'binary', name: 'binary' },
{ id: 'bit', name: 'bit' },
{ id: 'char', name: 'char' },
{ id: 'date', name: 'date' },
{ id: 'datetime', name: 'datetime' },
{ id: 'datetime2', name: 'datetime2' },
{ id: 'datetimeoffset', name: 'datetimeoffset' },
{ id: 'decimal', name: 'decimal' },
{ id: 'float', name: 'float' },
{ id: 'image', name: 'image' },
{ id: 'int', name: 'int' },
{ id: 'money', name: 'money' },
{ id: 'nchar', name: 'nchar' },
{ id: 'ntext', name: 'ntext' },
{ id: 'numeric', name: 'numeric' },
{ id: 'nvarchar', name: 'nvarchar' },
{ id: 'real', name: 'real' },
{ id: 'smalldatetime', name: 'smalldatetime' },
{ id: 'datetimeoffset', name: 'datetimeoffset' },
{ id: 'smallint', name: 'smallint' },
{ id: 'smallmoney', name: 'smallmoney' },
{ id: 'sql_variant', name: 'sql_variant' },
{ id: 'text', name: 'text' },
{ id: 'time', name: 'time' },
{ id: 'tinyint', name: 'tinyint' },
{ id: 'uniqueidentifier', name: 'uniqueidentifier' },
{ id: 'varbinary', name: 'varbinary' },
{ id: 'varchar', name: 'varchar' }
];
$scope.colOptions= [];
$scope.colOptions= [
{ id: '1', name: 'identity(1,1)' },
{ id: '2', name: 'constraint' }
];
$scope.typeCheck = function () {
alert($scope.dataType);
};
fiddle https://jsfiddle.net/5extmuqg/
#webdad3, cool. thanks for the fiddle.
This can be fixed with a couple of small changes. vm.datatypes (in your function) should become $scope.dataTypes. ANd the ng-model in your select should be dataType, NOT dataTypes. Lastly, in typeCheck(), also refer to $scope.dataType (singular).
the vm. notation is usually used when you want to use controller-as syntax rather than $scope. Since you're using $scope, just stick with that. And the ng-model for the <select> element should be the object you want to set, not the object providing the list of options.
Working Fiddle
Hope this helps

Resources