skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. You have a syntax error, instead of td you used th, that was the root cause of the issue.

    Before:

      <ng-container matColumDef="complete">
         <th mat-header-cell *matHeaderCellDef>Done</th>
         <th mat-cell *matCellDef="let item">{{ item.complete }}</th>
      </ng-container>
    

    After:

      <ng-container matColumnDef="complete">
         <th mat-header-cell *matHeaderCellDef>Complete</th>
         <td mat-cell *matCellDef="let item">{{ item.complete }}</td>
      </ng-container>
    

    Stackblitz Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search