I’m new to Angular 18. I want to integrate filter functionality into existing project. My project is generated with Angular CLI. I don’t understand how to merge together older angular 5 code with newer.
The code I’m trying to merge is a material table with filtering functionality, triggered on keyup event.
The code I want to integrate is here:
https://stackblitz.com/edit/angular-5hcooj?file=app%2Ftable-filtering-example.html
My code:
main.ts:
<code>import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
<code>import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
</code>
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
app.config.ts
<code>import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {provideHttpClient} from "@angular/common/http";
export const appConfig: ApplicationConfig = {
provideZoneChangeDetection({ eventCoalescing: true }),
provideAnimationsAsync(),
<code>import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {provideHttpClient} from "@angular/common/http";
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideAnimationsAsync(),
provideHttpClient()
]
};
</code>
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {provideHttpClient} from "@angular/common/http";
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideAnimationsAsync(),
provideHttpClient()
]
};
app.component.ts
<code>import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {MatToolbar} from "@angular/material/toolbar";
import {MatGridListModule} from "@angular/material/grid-list";
imports: [RouterOutlet, MatToolbar, MatGridListModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
export class AppComponent {
<code>import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {MatToolbar} from "@angular/material/toolbar";
import {MatGridListModule} from "@angular/material/grid-list";
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, MatToolbar, MatGridListModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'webapp';
}
</code>
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {MatToolbar} from "@angular/material/toolbar";
import {MatGridListModule} from "@angular/material/grid-list";
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, MatToolbar, MatGridListModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'webapp';
}
app.component.html
<code><router-outlet></router-outlet>
<code><router-outlet></router-outlet>
</code>
<router-outlet></router-outlet>
users/users.component.ts
<code>import {CdkTableModule} from '@angular/cdk/table';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {Component, OnInit, ViewChild, Input} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import {MatSort, Sort, MatSortModule} from '@angular/material/sort';
import {MatTableDataSource, MatTableModule} from '@angular/material/table';
import { User } from '../models/user.model'; // Define interfaces as needed
import { UserService } from '../services/user.service';
import {UserDetailComponent} from "../user-detail/user-detail.component";
import {MatGridListModule} from "@angular/material/grid-list";
import {MatFormField} from "@angular/material/form-field";
templateUrl: './users.component.html',
MatTableModule, MatSortModule, MatGridListModule, MatFormField
styleUrls: ['./users.component.css']
export class UsersComponent implements OnInit {
dataSource: MatTableDataSource<User>;
displayedColumns: string[] = ['id', 'name'];
constructor(private _liveAnnouncer: LiveAnnouncer, private userService: UserService, private dialog: MatDialog) {
this.dataSource = new MatTableDataSource<User>();
this.users = this.userService.getUsers();
this.dataSource.filterPredicate = function(data, filter: string): boolean {
return data.name.toLowerCase().includes(filter) || data.id.toString() === filter;
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = filterValue;
@ViewChild(MatSort) sort!: MatSort;
this.dataSource.sort = this.sort;
showUserDialog(user: User): void {
this.dialog.open(UserDetailComponent, {
/** Announce the change in sort state for assistive technology. */
announceSortChange(sortState: Sort) {
// This example uses English messages. If your application supports
// multiple language, you would internationalize these strings.
// Furthermore, you can customize the message to add additional
// details about the values being sorted.
if (sortState.direction) {
this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
this._liveAnnouncer.announce('Sorting cleared');
protected readonly HTMLInputElement = HTMLInputElement;
<code>import {CdkTableModule} from '@angular/cdk/table';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {Component, OnInit, ViewChild, Input} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import {MatSort, Sort, MatSortModule} from '@angular/material/sort';
import {MatTableDataSource, MatTableModule} from '@angular/material/table';
import { User } from '../models/user.model'; // Define interfaces as needed
import { UserService } from '../services/user.service';
import {UserDetailComponent} from "../user-detail/user-detail.component";
import {MatGridListModule} from "@angular/material/grid-list";
import {MatFormField} from "@angular/material/form-field";
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
standalone: true,
imports: [
MatTableModule, MatSortModule, MatGridListModule, MatFormField
],
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
dataSource: MatTableDataSource<User>;
users: User[] = [];
displayedColumns: string[] = ['id', 'name'];
constructor(private _liveAnnouncer: LiveAnnouncer, private userService: UserService, private dialog: MatDialog) {
this.dataSource = new MatTableDataSource<User>();
}
ngOnInit() {
this.users = this.userService.getUsers();
this.dataSource.filterPredicate = function(data, filter: string): boolean {
return data.name.toLowerCase().includes(filter) || data.id.toString() === filter;
};
}
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = filterValue;
}
@ViewChild(MatSort) sort!: MatSort;
@Input() filter!: User;
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
showUserDialog(user: User): void {
this.dialog.open(UserDetailComponent, {
width: '500px',
data: { user: user }
});
}
/** Announce the change in sort state for assistive technology. */
announceSortChange(sortState: Sort) {
// This example uses English messages. If your application supports
// multiple language, you would internationalize these strings.
// Furthermore, you can customize the message to add additional
// details about the values being sorted.
if (sortState.direction) {
this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
} else {
this._liveAnnouncer.announce('Sorting cleared');
}
}
protected readonly HTMLInputElement = HTMLInputElement;
}
</code>
import {CdkTableModule} from '@angular/cdk/table';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {Component, OnInit, ViewChild, Input} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import {MatSort, Sort, MatSortModule} from '@angular/material/sort';
import {MatTableDataSource, MatTableModule} from '@angular/material/table';
import { User } from '../models/user.model'; // Define interfaces as needed
import { UserService } from '../services/user.service';
import {UserDetailComponent} from "../user-detail/user-detail.component";
import {MatGridListModule} from "@angular/material/grid-list";
import {MatFormField} from "@angular/material/form-field";
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
standalone: true,
imports: [
MatTableModule, MatSortModule, MatGridListModule, MatFormField
],
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
dataSource: MatTableDataSource<User>;
users: User[] = [];
displayedColumns: string[] = ['id', 'name'];
constructor(private _liveAnnouncer: LiveAnnouncer, private userService: UserService, private dialog: MatDialog) {
this.dataSource = new MatTableDataSource<User>();
}
ngOnInit() {
this.users = this.userService.getUsers();
this.dataSource.filterPredicate = function(data, filter: string): boolean {
return data.name.toLowerCase().includes(filter) || data.id.toString() === filter;
};
}
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = filterValue;
}
@ViewChild(MatSort) sort!: MatSort;
@Input() filter!: User;
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
showUserDialog(user: User): void {
this.dialog.open(UserDetailComponent, {
width: '500px',
data: { user: user }
});
}
/** Announce the change in sort state for assistive technology. */
announceSortChange(sortState: Sort) {
// This example uses English messages. If your application supports
// multiple language, you would internationalize these strings.
// Furthermore, you can customize the message to add additional
// details about the values being sorted.
if (sortState.direction) {
this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
} else {
this._liveAnnouncer.announce('Sorting cleared');
}
}
protected readonly HTMLInputElement = HTMLInputElement;
}
users/users.component.html
<code><div class="example-container mat-elevation-z8">
<div class="example-header">
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
<mat-table #table [dataSource]="dataSource" matSort (matSortChange)="announceSortChange($event)">
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.id}} </mat-cell>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
<code><div class="example-container mat-elevation-z8">
<div class="example-header">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<mat-table #table [dataSource]="dataSource" matSort (matSortChange)="announceSortChange($event)">
<!-- Id Column -->
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.id}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
</code>
<div class="example-container mat-elevation-z8">
<div class="example-header">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<mat-table #table [dataSource]="dataSource" matSort (matSortChange)="announceSortChange($event)">
<!-- Id Column -->
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.id}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
The main.ts generated by Angular CLI is quite different from this:
<code>import './polyfills';
import {CdkTableModule} from '@angular/cdk/table';
import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
MatProgressSpinnerModule,
} from '@angular/material';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {TableFilteringExample} from './app/table-filtering-example';
MatProgressSpinnerModule,
export class DemoMaterialModule {}
entryComponents: [TableFilteringExample],
declarations: [TableFilteringExample],
bootstrap: [TableFilteringExample],
export class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);
<code>import './polyfills';
import {CdkTableModule} from '@angular/cdk/table';
import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import {
MatAutocompleteModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatStepperModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
} from '@angular/material';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {TableFilteringExample} from './app/table-filtering-example';
@NgModule({
exports: [
CdkTableModule,
MatAutocompleteModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
]
})
export class DemoMaterialModule {}
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
HttpClientModule,
DemoMaterialModule,
MatNativeDateModule,
ReactiveFormsModule,
],
entryComponents: [TableFilteringExample],
declarations: [TableFilteringExample],
bootstrap: [TableFilteringExample],
providers: []
})
export class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);
</code>
import './polyfills';
import {CdkTableModule} from '@angular/cdk/table';
import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import {
MatAutocompleteModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatStepperModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
} from '@angular/material';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {TableFilteringExample} from './app/table-filtering-example';
@NgModule({
exports: [
CdkTableModule,
MatAutocompleteModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
]
})
export class DemoMaterialModule {}
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
HttpClientModule,
DemoMaterialModule,
MatNativeDateModule,
ReactiveFormsModule,
],
entryComponents: [TableFilteringExample],
declarations: [TableFilteringExample],
bootstrap: [TableFilteringExample],
providers: []
})
export class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);