I am trying to follow through the book intitled "Pro Angular 16" and again, I am stuck early as the chapter 2 due to the following error, thrown by the TypeScript compiler embedded in Angular 18 developpment tools:
Error: Could not find column with id "complete".
The similar questions and answers associated allowed me not to resolve the problem so I am trying my luck here.
app.component.ts
import { Component } from '@angular/core';
import { TodoList } from "./todoList";
import { TodoItem } from "./todoItem";
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatBadgeModule } from '@angular/material/badge';
import { MatTableModule } from '@angular/material/table';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@Component({
selector: 'app-root',
standalone: true,
imports: [
FormsModule,
MatButtonModule, MatToolbarModule, MatIconModule, MatBadgeModule,
MatTableModule, MatCheckboxModule, MatFormFieldModule, MatInputModule, MatSlideToggleModule ],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'todo';
private list = new TodoList('Aurèle', [
new TodoItem("Finish the UBC website", true),
new TodoItem('Write some unit tests'),
new TodoItem('Learn Angular'),
new TodoItem('Write a word document for the jury'),
new TodoItem('Buy INCOSE book related to SysML v2', true),
]);
get username(): string {
return this.list.user;
}
get itemCount(): number {
return this.list.items.filter(item => !item.complete).length;
}
get items(): readonly TodoItem[] {
return this.list.items;
}
}
app.component.html
<div class="tableContainer">
<table mat-table [dataSource]="items" class="mat-elevation-z3 fullWidth">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>#</th>
<td mat-cell *matCellDef="let i = index">{{ i + 1 }}</td>
</ng-container>
<ng-container matColumnDef="task">
<th mat-header-cell *matHeaderCellDef>Task</th>
<td mat-cell *matCellDef="let item">{{ item.task }}</td>
</ng-container>
<ng-container matColumDef="complete">
<th mat-header-cell *matHeaderCellDef>Done</th>
<th mat-cell *matCellDef="let item">{{ item.complete }}</th>
</ng-container>
<tr mat-header-row *matHeaderRowDef="['id', 'task', 'complete']"></tr>
<tr mat-row *matRowDef="let row; columns: ['id', 'task', 'complete'];"></tr>
</table>
</div>
todoItem.ts
export class TodoItem {
constructor(public task: string, public complete: boolean = false) {
}
}
todoList.ts
import { TodoItem } from "./todoItem";
export class TodoList {
constructor(public user: string, private todoItems: TodoItem[] = []) {
}
get items(): readonly TodoItem[] {
return this.todoItems;
}
addItem(task: string) {
this.todoItems.push(new TodoItem(task));
}
}
The column id
does exist, so I am at a loss and have not the knowledge to resolve this blocking by myself.
2
Answers
The problem you are facing is that your
TodoItem
object does not have a property named "done".That is, in your HTML template you stated explicitly that the third column of the table must get populated from a property "done". Please find below the code snippet from your code that is looking for the "done" property:
So, you either add this property in
TodoItem
class/interface, or remove the mentioned column from your HTML template.You have a syntax error, instead of
td
you usedth
, that was the root cause of the issue.Before:
After:
Stackblitz Demo