i`m creating dynamic dropdown box i have 2 dropdown each of my dropdown have a different data once i selected it it will channge the other data depending on what you select in the first dropdown how to achieve that?
i tried this code but it gaves me a undentified
.TS
this is what iwanted to put in my dropdown box once i click the SERVICEABLE it will populate all the maintenance,upgrage,repairable and once i click the UNSERVICEABLE it will change it to another data and list all unserviceable
[
{
"id": 1,
"assetID": 9,
"tranType": "MAINTENANCE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 2,
"assetID": 9,
"tranType": "UPGRADE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 3,
"assetID": 9,
"tranType": "REPAIRABLE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 4,
"assetID": 10,
"tranType": "DISPOSAL",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
},
{
"id": 5,
"assetID": 10,
"tranType": "WRITTEN-OFF",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
},
{
"id": 6,
"assetID": 10,
"tranType": "RETIRED",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
}
]
assetDS: AssetCondtionDTO[];
assetObj: any;
'selectedType(trigger: MatSelectChange) {
this.assetObj = trigger.value;
const selectedItem = this.assetDS.find((x) => x.tranType.assetID == trigger.value);
if (selectedItem) this.serviceLogArray.get('tranType').patchValue(selectedItem.id);
console.log(this.assetObj)
}
assetCondition(){
this.serviceSVC.getAssetCondition(5,10).subscribe((res: AssetCondtionDTO) => {
this.assetObj = res;
})
}'
HTML
<td>
<mat-select formControlName="assetCondition" style="width:200px;padding:10px"
(selectionChange)="selectedType($event)">
<mat-option ngFor="let items of assetObj" [value]="items.id">
{{items.id}}
</mat-option>
</mat-select>
</td>
<td>
<mat-select formControlName="tranType" style="width:200px;padding:10px">
<mat-option ngFor="let items of assetObj" [value]="items.tranType.assetID">
{{items.tranType.tranType}}</mat-option></mat-select> </td> ```
CodePudding user response:
Code portion of your question is unclear and we can't understand written logic but from your description, I provide you an example to filter a fake list base on another select form control:
Template:
<form [formGroup]="formGroup">
<div>
<mat-select formControlName="assetCondition" style="width:200px;padding:10px"
(selectionChange)="selectedType($event)">
<mat-option *ngFor="let items of assetConditionTypes" [value]="items.id">
{{items.assetConditionType}}
</mat-option>
</mat-select>
</div>
<div>
<mat-select formControlName="tranType" style="width:200px;padding:10px">
<mat-option *ngFor="let items of filteredAssets" [value]="items.assetID">
{{items.tranType}}
</mat-option>
<mat-option *ngIf="filteredAssets.length===0">
Pleas select type first!
</mat-option>
</mat-select>
</div>
</form>
TS:
formGroup: FormGroup = new FormGroup({
assetCondition: new FormControl(''),
tranType: new FormControl('')
});
selectedType(trigger: MatSelectChange) {
this.filteredAssets = this.myAssets.filter((asset) => asset.assetConditionType.id == trigger.value);
console.log(this.filteredAssets);
}
assetConditionTypes = [
{
"id": 9,
"assetConditionType": "SERVICEABLE"
},
{
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
];
filteredAssets: any[] = [];
myAssets = [
{
"id": 1,
"assetID": 9,
"tranType": "MAINTENANCE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 2,
"assetID": 9,
"tranType": "UPGRADE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 3,
"assetID": 9,
"tranType": "REPAIRABLE",
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
{
"id": 4,
"assetID": 10,
"tranType": "DISPOSAL",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
},
{
"id": 5,
"assetID": 10,
"tranType": "WRITTEN-OFF",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
},
{
"id": 6,
"assetID": 10,
"tranType": "RETIRED",
"assetConditionType": {
"id": 10,
"assetConditionType": "UNSERVICEABLE"
}
}
];
CodePudding user response:
First you need transform your data "grouping" in an object like
[
{
"id": 9,
"assetConditionType": "SERVICEABLE",
"items": [
{
"id": 1,
"assetID": 9,
"tranType": "MAINTENANCE"
"assetConditionType": {
"id": 9,
"assetConditionType": "SERVICEABLE"
}
},
...
]
}
...
]
For this we use reduce. Reduce it's no so complex looks like. Imagine you has an array data
const dataTransformed=data.reduce((a,b)=>{
return function(a,b)
},initial)
If like a loop
let a=initial
for (let i=0;i<data.length;i )
{
b=data[i];
a=function(a,b)
}
const dataTransformed=a
So you can use reduce and rxjs map operator in the way
getData(){
return this.httpClient.get(..your url...).pipe(
map((data: any[]) => {
const groupData=data.reduce((a: any, b: any) => {
const id = b.assetConditionType.id;
const element = a.find((x: any) => x.id == id);
if (element) element.items.push(b);
else
{
a.push({
id: id,
assetConditionType: b.assetConditionType.assetConditionType,
items: [b],
});
}
return a;
}, []);
return groupData
})
);
}
One time you has your data grouped, as you has a few data you can use some like
<mat-form-field appearance="fill">
<mat-label>Asset</mat-label>
<mat-select [(ngModel)]="value" (selectionChange)="value2=null">
<mat-option *ngFor="let item of obs|async" [value]="item">
{{item.assetConditionType}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Transation</mat-label>
<mat-select [(ngModel)]="value2">
<mat-option *ngFor="let item of value?.items" [value]="item">
{{item.tranType}}
</mat-option>
</mat-select>
</mat-form-field>
See that "value" has the whole object grouped, so we can use value.items to give value to the options of the second dropdown
I use [(ngModel)] you can use ReactiveForms. If only are interesting in the "items" only use a FormControl to get the item.
Some like
form=new FormGroup({
asset:new FormControl()
})
<form [formGroup]="form">
<mat-form-field appearance="fill">
...
<mat-select [(ngModel)]="value" (selectionChange)="value2=null">
[ngModelOptions]="{standalone:true}"
<mat-option *ngFor="let item of obs|async" [value]="item">
{{item.assetConditionType}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill">
...
<mat-select formControlName="asset">
<mat-option *ngFor="let item of value?.items" [value]="item">
{{item.tranType}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
See that the "value" is not belong to the form (it's only a auxiliar variable). As not belong to the form you use [(ngModel)]
and [ngModelOptions]="{standalone:true}"
NOTE: If you only want the "id" use in the second dropdown [value]="item.id"