In the last module we set up a search panel area. Let’s start filling it in.
In Chapter 01 we created a side panel where we could search for vehicles by category; Car, Truck, or Jeep. The screenshot below is what it looks like.

In the screen shot above the buttons are styled with Bootstrap since that is the CSS library we used in Chapter 1. Since we are using the Angular Material component library now, let’s try something a little different. Let’s set up the category search with some MatCheckbox components.
In chapter 1 we could select ‘All’, ‘Cars’, ‘Trucks’, or ‘Jeeps’. But we could not select both Cars and Trucks, or Trucks and Jeeps. In this new UI will be able to select any combination of categories as we soon shall see. The screen shot below shows an example where the combination of Trucks and Jeeps are selected.

In the screenshot above, only Truck and Jeep are selected. So the All category checkbox instead of having a checkmark shows shows a dash. This is called the indeterminate
state. The other states are checked
and unchecked
; checked being when Car, Truck, and Jeep are all selected, and unchecked being when none of the selections are checked. This is the interface we are going to create. So let’s get to work!
- Import MatCheckboxModule
- Create an ASP.Net Core API Controller
- Test the VehicleTypes web service
- Define the VehicleType Interface
- Define the Category Interface
- Modify the Vehicles component TypeScript: Create the Categories
- Modify the Vehicles component HTML
- Test the Category UI
- Removethe debug settings
- What's Next
Import MatCheckboxModule
Open angular-material.module.ts and make the code modifications below in bold blue font.
FredsCars/src/app/angular-material.module.ts
import { NgModule } from '@angular/core';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatTableModule } from '@angular/material/table';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatCheckboxModule } from '@angular/material/checkbox';
const angularMatModules = [
MatToolbarModule,
MatIconModule,
MatButtonModule,
MatTableModule,
MatProgressSpinnerModule,
MatPaginatorModule,
MatSortModule,
MatSidenavModule,
MatCheckboxModule
]
@NgModule({
imports: [
angularMatModules
],
exports: [
angularMatModules
]
})
export class AngularMaterialModule { }
In the code above we are once again simply importing the Angular Material module of the component we want to use, in this case MatCheckbox.
Create an ASP.Net Core API Controller
In the new UI shown above, we are going to want to fetch the category names dynamically just like we do the actual vehicle results. And we already made the decision earlier on when we created the Vehicles ASP.Net Core API controller that although status (New or Used) can be an enum, we are going to store VehicleTypes in the database. So we are going to create a VehicleTypes controller to return the Categories from a database on the ASP.Net Core side.
Create a file called VehicleTypesController.cs in the FredsCarsAPI/Controllers folder and fill it with the contents below.
FredsCarsAPI/Controllers/VehicleTypesController.cs
using FredsCarsAPI.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace FredsCarsAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class VehicleTypesController : ControllerBase
{
[HttpGet]
public IEnumerable<VehicleType> GetVehicles()
{
var vehicleTypes = new List<VehicleType>
{
new VehicleType { Id = 1, Name = "Car" },
new VehicleType { Id = 2, Name = "Truck" },
new VehicleType { Id = 3, Name = "Jeep" }
};
return vehicleTypes;
}
}
}
In the code above we simply define an HTTP GET rest service called VehicleTypes. In the GET method we define a variable called vehicleTypes of type List<VehicleType>
and fill it with static VehicleType objects. Rest assured we will make all of our data dynamic and pull from a database in upcoming modules. But for now this will do the trick and let us continue developing our Angular application.
Test the VehicleTypes web service
Run the FredsCarsAPI project in debug mode by right clicking on FredsCarsAPI in Solution Explorer and selecting Debug --> Start New Instance
.

Open Postman and create a GET request for the following URL.
https://localhost:40443/api/VehicleTypes
If you haven’t installed Postman yet you can find a tutorial for installing and running Postman at Installing Postman on my blog.
Hit Send to execute the request and the JSON results should look like the following.

In the screenshot above you can see we have returned a JSON array of Vehicle objects from our web service.
Define the VehicleType Interface
The next step is to define a TypeScript interface for VehicleType on the Angular side just as we did for Vehicles.
Create a file called vehicleType.ts in the FredsCars/src/app/vehicles folder and fill it with the contents below:
FredsCars/src/app/vehicles/vehicleType.ts
export interface VehicleType {
id: number;
name: string;
}
Define the Category Interface
Now that we have our web service and client-side interface in place we can fetch VehicleType data and lay out our checkboxes right? Well, almost. Our C# VehicleType object and Angular VehicleType interface both have two properties: id, and name. But for the checkboxes we to also need to track whether each checkbox is selected. And we need a way to structure our categories so that the All checkbox is considered the main category. And the Car, Truck, and Jeep categories are considered subcategories. This will let us set whether the All checkbox is in the indeterminate, checked, or unchecked state we talked about earlier looking at the new UI screenshot.
So let’s tackle that right now. Open up the vehicleType.ts file in the Angular application and modify it with the code below.
FredsCars/src/app/vehicles/vehicleType.ts
export interface VehicleType {
id: number;
name: string;
}
export interface Category {
id: number;
name: string;
selected: boolean;
categories?: Category[]
}
In the code above we have added a new Category interface much like our VehicleType interface. But Category contains an extra property called selected
of type boolean to allow us to track whether each checkbox is selected or not. It also contains a property called categories
of type Category Array to store our Car, Truck, and Jeep subcategories.
Modify the Vehicles component TypeScript: Create the Categories
Now that we have a Category interface to work with, we can create a variable of that type, fetch all VehicleTypes from our new API service, transform them into Categories, and store them in the variable’s categories array.
Open the vehicles.component.ts file and make the modifications below in bold blue font.
FredsCars/src/app/vehicles/vehicles.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Vehicle } from './vehicle';
import { environment } from '../../environments/environment';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from "@angular/material/paginator";
import { MatSort } from "@angular/material/sort";
/* Import */
import { Category, VehicleType } from './vehicleType';
@Component({
selector: 'app-vehicles',
templateUrl: './vehicles.component.html',
styleUrls: ['./vehicles.component.scss']
})
export class VehiclesComponent implements OnInit {
// debug JSON var for HTML
public json = JSON;
public vehicles: MatTableDataSource<Vehicle>
columnsToDisplay: string[] = ['id', 'vehicleType', 'status', 'year', 'make', 'model', 'color', 'price'];
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
categoryAll: Category = {
id: 0,
name: 'All',
selected: false,
categories: []
};
allCategoriesSelected: boolean = false;
constructor(private http: HttpClient) {
this.vehicles = new MatTableDataSource<Vehicle>();
}
ngOnInit() {
// get vehciles
this.http.get<Vehicle[]>(environment.baseUrl + 'api/vehicles').subscribe(result => {
this.vehicles.data = result;
}, error => console.error(error));
// get vehicleTypes and transform into search catgories
this.http.get<VehicleType[]>(environment.baseUrl + 'api/vehicleTypes').subscribe(result => {
result.forEach(vt => {
this.categoryAll.categories?.push(
{
id: vt.id,
name: vt.name,
selected: false
}
);
})
}, error => console.error(error));
}
ngAfterViewInit() {
this.vehicles.paginator = this.paginator;
this.vehicles.sort = this.sort;
}
/*** Categogry Search Checkbox methods ***/
public someSearchCategoriesSelected(): boolean {
return this.categoryAll.categories!.filter(cat =>
cat.selected).length > 0 && !this.allCategoriesSelected;
}
setAllCategoriesSelected(checked: boolean) {
this.allCategoriesSelected = checked;
this.categoryAll.selected = checked;
this.categoryAll.categories!.forEach(cat =>
(cat.selected = checked));
}
updateAllCategoriesSelected() {
var allSelected: boolean =
this.categoryAll.categories!.every(cat =>
cat.selected);
this.allCategoriesSelected = allSelected;
this.categoryAll.selected = allSelected;
}
/*** End Categogry Search Checkbox methods ***/
}
Let’s take a few minutes to look at the new code sprinkled into the Vehicles component TypeScript.
The first thing we did at the top of the TypeScript was import the new Category
and already existing VehcileType
interfaces so we can use them below in the code.
Next in the top line of the VehcilesComponent class we create a variable called json of type JSON. We will use the JSON object on the front end to set up a debug panel so we can see the state of the Angular Checkboxes model update live while we test checking and unchecking combinations of checkboxes.
public json = JSON;
Then we create a variable called categoryAll of type Category, the interface we just created.
The categoryAll variable will have an id of 0 representing all categories chosen, a name of All, and initially have a selected value of false, or unchecked. The categories array property is initialized to an empty array which we will fill with VehicleTypes transformed to Categories in ngOnInit.
categoryAll: Category = {
id: 0,
name: 'All',
selected: false,
categories: []
};
We also create a variable called allCategoriesSelected of type boolean. If this variable is true, then the All checkbox should be checked. It starts off initialized to false.
allCategoriesSelected: boolean = false;
In ngOnInit, we add a second HTTP Get call to the new VehicleTypes API service. We subscribe to the returned Observable which is an array of VehicleType. Then we loop through the VehicleTypes (Car, Truck, and Jeep) transforming each one into a Category and pushing it onto the categoryAll.categories
subcategory array.
// get vehicleTypes and transform into search catgories
this.http.get<VehicleType[]>(environment.baseUrl + 'api/vehicleTypes').subscribe(result => {
result.forEach(vt => {
this.categoryAll.categories?.push(
{
id: vt.id,
name: vt.name,
selected: false
}
);
})
}, error => console.error(error));
At the bottom of the TypeScript we have three methods to help manage our Category Checkbox model and states.
The first method is called someSearchCategoriesSelected
. This method helps us figure out if only some of the Categories, but not all, are selected by using the Array.filter()
method on the categoryAll.categories
property to check if it has at least one category selected but not all categories. We know whether all categories are selected by checking the new allCategoriesSelected
variable we just created.
public someSearchCategoriesSelected(): boolean {
return this.categoryAll.categories!.filter(cat =>
cat.selected).length > 0 && !this.allCategoriesSelected;
}
The second method is called setAllCategoriesSelected
. This method takes in a parameter called checked of type boolean. This method will receive an event whenever the All Checkbox is checked or unchecked, true or false respectively, and set allCategoriesSelected
(needed above in someSearchCategoriesSelected) and the categoryAll.selected
property. Then we loop through the subcategories in the categoryAll.categories
property (updating the Angular live data model) to true or false.
setAllCategoriesSelected(checked: boolean) {
this.allCategoriesSelected = checked;
this.categoryAll.selected = checked;
this.categoryAll.categories!.forEach(cat =>
(cat.selected = checked));
}
The third and final method is called updateAllCategoriesSelected
. This method will be fired everytime a user checks or unchecks one of the subcategories; Car, Truck, or Jeep. It has a local variable called allSelected
of type boolean. As users select and unselect the Car, Truck, and Jeep categories, the allSelected
local variable gets set to the result of a lamda expression passed to the every()
method of the categoryAll.categories
property. The every() expression returns true if the expression passed to it is true for every element, in this case every subcategory is selected, and false otherwise. Finally we update allCategoriesSelected
and the categoryAll.selected
property just as we do in the setAllCategoriesSelected
method above.
updateAllCategoriesSelected() {
var allSelected: boolean =
this.categoryAll.categories!.every(cat =>
cat.selected);
this.allCategoriesSelected = allSelected;
this.categoryAll.selected = allSelected;
}
This wasn’t really a lot of code we just added except for the three helper methods at the end. They may seem a little difficult to understand at this point, especially without first having modified and studied the HTML in the template. But once we do that we will see it all makes sense. And, we will see the power of databinding MatCheckbox attributes and events to these new variables and helper methods.
Modify the Vehicles component HTML
Now that we have done the preparation in the TypeScript to support the checkbox selections and the categories portion of the Angular data model, we can finally build the Categories selection UI with MatCheckbox.
Open the vehicles.component.html file and make the modifications below in blue bold font.
FredsCars/src/app/vehicles/vehicles.component.html
<mat-sidenav-container autosize>
<mat-sidenav mode="side" #sidenav opened>
<div style="margin-right: 10px;">
<p><b>Search Panel</b></p>
<hr />
<p><b>Categories</b></p>
<mat-checkbox color="primary"
[checked]="allCategoriesSelected"
[indeterminate]="someSearchCategoriesSelected()"
(change)="setAllCategoriesSelected($event.checked)">
{{ categoryAll.name }}
</mat-checkbox>
<ul>
<li *ngFor="let category of categoryAll.categories">
<mat-checkbox color="accent"
[(ngModel)]="category.selected"
(ngModelChange)="updateAllCategoriesSelected()">
{{category.name}}
</mat-checkbox>
</li>
</ul>
<!-- debug -->
<b>categoryAll:</b><br />
{{ categoryAll.selected }}<br />
<b>Categories:</b>
<ul>
<li *ngFor="let category of categoryAll.categories">
{{category.name}}: {{ category.selected}}
</li>
</ul>
<!-- end debug-->
</div>
</mat-sidenav>
<mat-sidenav-content>
<p *ngIf="!vehicles">
<mat-spinner style="margin: 0 auto;"></mat-spinner>
</p>
<!-- existing content -->
<!-- ToDo: Change pageSize back to 5-->
<mat-paginator [pageSize]="10" [pageSizeOptions]="[3, 5, 10]">
</mat-paginator>
</mat-sidenav-content>
</mat-sidenav-container>
Import FormsModule
In the html above we use ngModel
to implement two way databinding to bind each subcategory’s selected
property to the data model. We’ll talk more about this when we go back and inspect the html. But, before we can run the application and see what it looks like we need to import FormsModule
in order for ngModel
to work.
Open the app.module.ts file and make the modifications below.
FredsCars/src/app/app.module.ts
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { VehiclesComponent } from './vehicles/vehicles.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
VehiclesComponent,
WelcomeComponent,
NavMenuComponent,
HeaderComponent,
FooterComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
BrowserAnimationsModule,
AngularMaterialModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
CSS for list-items
For the last tweak before we run the application we need to remove the bullet points from the category list-items. We just want the indenting a list-item gives, not the bullet points. Open the vehicles.component.scss file and make the following modifications.
FredsCars/src/app/vehicles/vehicles.component.scss
/* existing code */
li {
list-style: none;
}
Now if we run the application, it should look similar to the following screenshot.

Let’s inspect the vehicles component html above and then we’ll go through some examples of how it works.
The first thing we did was add the opened attribute to the mat-side-nav element.
<mat-sidenav mode="side" #sidenav opened>
This attribute starts the SideNav off in the opened position so we don’t have to keep clicking the search glass icon to open the SideNav back up every time we make a change and hot reload reloads the browser. We will remove this attribute at the end of the module.
The next thing we did was add a Categories label in bold tags and a mat-checkbox element.
<hr />
<p><b>Categories</b></p>
<mat-checkbox color="primary"
[checked]="allCategoriesSelected"
[indeterminate]="someSearchCategoriesSelected()"
(change)="setAllCategoriesSelected($event.checked)">
{{ categoryAll.name }}
</mat-checkbox>
The mat-checkbox
element has it’s color attribute set to primary so it will have the indigo-pink theme’s primary color when checked. We bind the checked
attribute to the allCategoriesSelected
variable we manage in the TypeScript. The indeterminate
attribute gets bound to our someSearchCategoriesSelected()
checkbox helper method. And we bind the change event to our setAllCategoriesSelected()
checkbox helper method. When a user checks or unchecks the All checkbox, the change event is fired, and an event with the All checkbox’s checked state is passed as a parameter to setAllCategoriesSelected()
. Finally we lay out the label text of the checkbox using one way databinding to display the name
property of categoryAll
which we initialized to ‘All’ in the TypeScript.
After the All checkbox, we lay out an unordered list of mat-checkbox
to represent the subcategories; Car, Truck, and Jeep.
<ul>
<li *ngFor="let category of categoryAll.categories">
<mat-checkbox color="accent"
[(ngModel)]="category.selected"
(ngModelChange)="updateAllCategoriesSelected()">
{{category.name}}
</mat-checkbox>
</li>
</ul>
Here we use the ngFor
structural directive to lay out a list-item
for each subcategory. Each list-item
contains as its contents a mat-checkbox
element. And each mat-checkbox
has it’s color attribute set to accent so it will have the indigo-pink theme’s accent color when checked. The ngModel
attribute is bound to each subcategory’s selected
property creating two way databinding. This creates the affect where when the user clicks the Car, Truck, or Jeep checkboxes, their selected
property is updated in the Angular live data model. And when our setAllCategoriesSelected()
helper method updates all the subcategory selected
properties (as a result of the user checking the All checkbox), the subcategory checkboxes gets checked or unchecked depending on the update to the model. The ngModelChange
event is bound to our updateAllCategoriesSelected
() helper method. ngModelChange
is the output of ngModel
. So when the model changes it calls our updateAllCategoriesSelected()
helper. The label text of each checkbox is set with {{category.name}}
, the name property of each subcategory, as the value of the mat-checkbox element.
In the last portion we create a little debug panel so we can watch the data model update as we check and uncheck categories.
<!-- debug -->
<b>categoryAll:</b><br />
{{ categoryAll.selected }}<br />
<b>Categories:</b>
<ul>
<li *ngFor="let category of categoryAll.categories">
{{category.name}}: {{ category.selected}}
</li>
</ul>
<!-- end debug-->
Our debug panel code is very similar to how we lay out the subcategory checkboxes. First we display the categoryAll.selected
property so we can view the state of the All checkbox in the datamodel as we check and uncheck it. Then we use ngFor
to lay out the category name and selected state for each subcategory checkbox so we can view the selected state for Car, Truck, and Jeep live in the datamodel as the user checks and unchecks them.
One last thing we did was set the default pageSize of the MatPaginator to 10.
<!-- ToDo: Change pageSize back to 5-->
<mat-paginator [pageSize]="10" [pageSizeOptions]="[3, 5, 10]">
</mat-paginator>
The reason we did this is because with pageSize set at 5 rows, the vehicles table does not create enough height for the debug panel and a vertical scrollbar shows up for the MatSidenav sidebar. We don’t want to have to keep scrolling down to view the data model when we make changes.

Test the Category UI
Now that we have everything in place, let’s run through some examples to test the Categories selection UI.
Check a subcategory
Let’s start off by clicking one subcategory. Click the Truck checkbox and your browser should look similar the screenshot below.

In the screenshot above, by clicking the Truck checkbox, the selected
property of Truck in categoryAll.categories
in the Typescript becomes true which we can see in our debug panel near the bottom. Also since some of the subcategories are selected (at least one), the All checkbox is put in the indeterminate state with a dash.
Check the All checkbox
Click the All checkbox and your browser will look similar to the following screenshot.

When we checked the All checkbox, the two unchecked subcategory checkboxes became checked; Car and Jeep. The selected properties for All, Car, and Jeep became true in the debug panel, and the All checkbox was put in the checked state with a checkmark.
Uncheck the All checkbox
Click the All checkbox to uncheck it and your browser will look similar to the following screenshot.

By unchecking the All checkbox, the Car, Truck, and Jeep checkboxes were unchecked and the selected
properties of All, and Car, Truck, and Jeep were set to false.
You can play around yourself with more checking and unchecking combinations to make sure everything is working correctly.
Removethe debug settings
We can remove the debug settings from the HTML at the this point.
- Remove the
open
attribute frommat-sidenav
element. - Set the
pageSize
attribute for themat-paginator
element back to 5. - Comment out the debug panel in the sidenav for now.
The following code is the complete vehicles component HTML at the end of this module.
<mat-sidenav-container>
<mat-sidenav mode="side" #sidenav>
<div style="margin-right: 10px;">
<p><b>Search Panel</b></p>
<hr />
<p><b>Categories</b></p>
<mat-checkbox color="primary"
[checked]="allCategoriesSelected"
[indeterminate]="someSearchCategoriesSelected()"
(change)="setAllCategoriesSelected($event.checked)">
{{ categoryAll.name }}
</mat-checkbox>
<ul>
<li *ngFor="let category of categoryAll.categories">
<mat-checkbox color="accent"
[(ngModel)]="category.selected"
(ngModelChange)="updateAllCategoriesSelected()">
{{category.name}}
</mat-checkbox>
</li>
</ul>
<!-- debug -->
<!--
<b>categoryAll:</b><br />
{{ categoryAll.selected }}<br />
<b>Categories:</b>
<ul>
<li *ngFor="let category of categoryAll.categories">
{{category.name}}: {{ category.selected }}
</li>
</ul>
-->
<!-- debug -->
</div>
</mat-sidenav>
<mat-sidenav-content>
<p *ngIf="!(vehicles.data.length > 0)">
<mat-spinner style="margin: 0 auto;"></mat-spinner>
</p>
<div>
<button mat-icon-button
color="primary"
(click)="sidenav.toggle()">
<mat-icon>
search
</mat-icon>
</button>
</div>
<table mat-table [dataSource]="vehicles" matSort
[ngClass]="{'hide-results' : vehicles.data.length <= 0}">
<ng-container matColumnDef="vehicleType">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Category</th>
<td mat-cell *matCellDef="let item">
<b>{{ item.vehicleType }}</b>
</td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let item">
{{ item.id }}
</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
<td mat-cell *matCellDef="let item">
{{ item.status }}
</td>
</ng-container>
<ng-container matColumnDef="year">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Year</th>
<td mat-cell *matCellDef="let item">
{{ item.year }}
</td>
</ng-container>
<ng-container matColumnDef="make">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Make</th>
<td mat-cell *matCellDef="let item">
{{ item.make }}
</td>
</ng-container>
<ng-container matColumnDef="model">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Model</th>
<td mat-cell *matCellDef="let item">
{{ item.model }}
</td>
</ng-container>
<ng-container matColumnDef="color">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Color</th>
<td mat-cell *matCellDef="let item">
{{ item.color }}
</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Price</th>
<td mat-cell *matCellDef="let item">
<b>{{ item.price | currency:"USD" }}</b>
</td>
</ng-container>
<!-- No VIN on vehicles page. We will show this on the details page -->
<!-- Header Template -->
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<!-- Row Template -->
<tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
</table>
<mat-paginator [pageSize]="5"
[pageSizeOptions]="[3, 5, 10]"
[ngClass]="{'hide-results' : vehicles.data.length <= 0}">
</mat-paginator>
</mat-sidenav-content>
</mat-sidenav-container>
What’s Next
Well, I think we covered a lot of ground in this module. We learned about and used the MatCheckbox component from the Angular Material library. And we wired up the checkboxes to manage an instance of the categoryAll
interface we created and added to the data model.
We are not going to implement the vehicle results being filtered down by the category checkboxes UI yet. We need to get some background on how forms work in Angular first before we do that.
And in the upcoming modules that’s exactly what we’ll do when we build update
and create
components to allow users to edit and add vehicles. And then we will return to implementing some search features in our cool sidebar. But first we are going to make another house cleaning pitstop and add an image to our welcome page to make it look a little nicer. And then we are going to replace our mock data with a real database using Entity Framework Core migrations.