Reputation: 3548
I am using ngFor to iterate a collection of a specific type [Menu] in Angular 4.x.
Then looping on a collection property of the menu object (menu.items).
Unfortunately, the property is unknown in my IDE (Eclipse + Angular IDE), even though the Menu class defines the items property as an array of MenuItem.
Is there a solution?
Relevant class declarations -
export class MenuBase {
id: string;
title: string;
isPublic: boolean;
roles: string[];
items: MenuItem[];
position: number;
// rest of class omitted
}
export class MenuItem extends MenuBase {
menuItemType: MenuItemType;
callback: () => void;
location: string;
constructor (options: any) {
super(options);
this.location = options.location;
this.menuItemType = options.menuItemType || MenuItemType.location;
this.callback = options.callback;
}
}
export class Menu extends MenuBase {
constructor (options: any) {
super(options);
}
}
This is the project I was working on: https://github.com/savantly-net/ngx-menu. The project will show an error in Eclipse, even though it's valid.
I never created any documentation, but I used it here - https://github.com/savantly-net/sprout-platform/tree/master/web/sprout-web-ui
Upvotes: 20
Views: 15217
Reputation: 149
BTW: In Visual Studio Code, you need to specify it within the appropriate tsconfig.json file:
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInputTypes": true,
}
Upvotes: 2
Reputation: 56936
You can use a pipe to work around this. This code was throwing a type error:
<ng-container *ngIf="(item.value.value - defaultCssFilters[item.key].value) > 0">
...
</ng-container>
To fix it I used a pipe:
<ng-container *ngIf="(item.value.value - (defaultCssFilters | filterValue: item.key)) > 0">
...
</ng-container>
The pipe looks like this:
@Pipe({ name: 'filterValue' })
export class FilterValuePipe implements PipeTransform {
transform(cssFilters: ICssFilters, key: TCssFilter): number {
return cssFilters[key].value;
}
}
This works because in the pipe you can declare your types.
When working with existing code, this is far less cumbersome than creating a new component.
Upvotes: 1
Reputation: 6529
What I've had success with is creating a new component for the template that the *ngFor
will render and have that typed.
Container template:
<ng-container *ngFor="item of items" >
<my-custom-component [item]="item"></my-custom-component>
</ng-container>
Custom Component template:
<div *ngIf="item.menuItemType == 'dropdown'">
<!-- -->
</div>
ts file:
@Component({})
export class MyCustomComponent {
@Input() item: MenuItem
}
Upvotes: 12