Reputation: 12237
I have created a small dropdown component which takes the following interface as <option>
s:
interface DropdownSelectChoice {
label: string;
key: string;
}
The component to accepts a one- or two-dimensional array of choices
@Input() choices: DropdownSelectChoice[] | DropdownSelectChoice[][];
and if a two-dimensional array of choices is passed, to create unlabelled <optgroup>
s of each set of choices:
<span [class.disabled]="disabled">
<select (ngModelChange)="choose($event)"
[disabled]="disabled"
[(ngModel)]="defaultChoice">
<ng-container *ngIf="choices[0].constructor === Array">
<optgroup *ngFor="let group of choices" [label]="null">
<option *ngFor="let choice of group"
[value]="choice.key">
{{ choice.label }}
</option>
</optgroup>
</ng-container>
<ng-container *ngIf="choices[0].constructor !== Array">
<option *ngFor="let choice of choices"
[value]="choice.key">
{{ choice.label }}
</option>
</ng-container>
</select>
</span>
If I pass it a one-dimensional array, it works as expected:
choices: DropdownSelectChoice[] = [
{
label: "One",
key: "1"
},
{
label: "Two",
key: "2"
}
];
If I pass it a two-dimensional array:
choicesGroup: DropdownSelectChoice[][] = [
[
{
label: "One",
key: "1"
},
{
label: "Two",
key: "2"
}
],
[
{
label: "Three",
key: "3"
},
{
label: "Four",
key: "4"
}
]
];
I get choicesGroup.length
blank <option>
s with no <optgroup>
.
Setting a break-point in the drop down component's initialiser, I confirm that this.choices[0].constructor === Array
is true
when passing choicesGroup
, but the template seems always to be evaluating the !== Array
template path.
What silly thing have I omitted that I am not noticing?
Upvotes: 3
Views: 2304
Reputation: 12237
For the sake of completeness -- informed by Günter's accepted answer, these are my final changes:
private grouped: boolean;
ngOnInit() {
this.grouped = this.choices[0].constructor === Array;
}
And in the template, I changed the ng-container's conditions to:
<ng-container *ngIf="grouped">...</ng-container>
<ng-container *ngIf="!grouped">...</ng-container>
Upvotes: 0
Reputation: 657821
Types can't be used this way in templates.
Try
<ng-container *ngIf="choices[0].isArray">
<ng-container *ngIf="!choices[0].isArray">
if you still want to use constructor === Array
you need to create a method and do the comparison there.
<ng-container *ngIf="isArray(choices[0])">
isArray(obj) {
return obj.constructor === Array;
}
Upvotes: 3