Code on github https://github.com/kendarorg/Angular101

The list of addresses

Let's start showing the list of addresses

ng generate component Addresses

And four new files are now created, describing the new component, adding them to the main app.module.ts

Routing

Let's start the ng serve in backround. This will listen to file system changes and recompile everything accordingly showing errors too!

I assume that the first page will be the one showing all the addresses. But the default routing should point to the addresses component.

I need to modify the app-routing.module. Let's dissect it. First there is the import for the core of angular js, with a "node_modules" based path, denoted via the @ sign. It means, seek for the module core under the current angular version directory, and from the core angular stuffs import NgModule. The same for router

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

Then an empty list of routes is exposed (that will be filled afterwards)

const routes: Routes = [];

Finally the main application is initialized, exporting are initialized NgModule and AppRoutingModule

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

This will be used inside the app.module.ts file to start the application

First adding the import for the new component to the list of imports

import { AddressesComponent } from './addresses/addresses.component';

Then adding the new default route to the list of routes:

const routes: Routes = [
    {path: "", component: AddressesComponent},
];

Now ,refreshing the page will return a catching text: addresses works!

Furnishing some "real" data

It is then possible to expose some data. We create a simple service

ng generate service AddressesData

Generating two files

Something special for this example is a clone method to consume and produce only cloned items. This way the content of the data storage will be disconnected from the ui

    private clone<T>(a: T): T {
      return JSON.parse(JSON.stringify(a));
    }

Now we can fill the latter with some fake data inside the class declaration. Note the type declaration, array of AddressElement

  addresses: AddressElement[] = [
    {id: 1, name: "Contact A", address: "A road", email: "a@b.com"},
    {id: 2, name: "Contact B", address: "B road", email: "b@c.com"},
    {id: 3, name: "Contact C", address: "C road", email: "c@d.com"},
    {id: 4, name: "Contact D", address: "D road", email: "d@e.com"},
    {id: 5, name: "Contact E", address: "A road", email: "e@b.com"},
    {id: 6, name: "Contact F", address: "B road", email: "f@c.com"},
    {id: 7, name: "Contact G", address: "C road", email: "g@d.com"},
    {id: 8, name: "Contact H", address: "D road", email: "h@e.com"}
  ];

  public getAddresses():Array<AddressElement>{
    var result= [] as AddressElement[];
    for(var  i=0;i< this.addresses.length;i++){
        result.push(this.clone(this.addresses[i]));
    }
    return result;
  }

Let's examine a bit more. Before the class declaration there is an annotation. This is needed by all the services. It means that the service will be "stored" inside the root dependency injection context.

@Injectable({
  providedIn: 'root'
})

Additionally the definition of the data is added

export interface AddressElement {
  name: string;
  id: number;
  address: string;
  email: string;
}

The controller

First we need to import the data service. Notice the "../" part. We are setting a relative path for the import. The definition of AddressElement is imported too

import { AddressesDataService, AddressElement } from '../addresses-data.service';

Then the constructor must be changed to include the data service just imported and will be changed to the following. Creating a variable data service, initialized with the instance just imported.

constructor(public dataService: AddressesDataService) { }

We can now add the initialization with the onInit method and a function to select the...selected address, with the relative fields.

addresses: Array<AddressElement>;

ngOnInit(): void {
    this.addresses = this.dataService.getAddresses();
}

Finally a variable containing the the columns to show is added

displayedColumns: string[] = ['name', 'address', 'email'];

Showing the table

We are using the "material" library for our application. Specifically we use the MatTableModule. It must first be imported inside the app.module.ts

import { MatTableModule } from '@angular/material/table'; 

And added into the @NgModule

@NgModule({
    ...
    imports: [
        ...
        MatTableModule,
    ],

Now all the application will have access to this module!

The template of the addesses component, inside addresses.component.html, must now show the list! I add too the id cell of the object that will be useful in further explanations.

A "mat-table" is created using a "[dataSource]" NOTE THE SQUARE BRACKETS. Inside it are defined all the possible columns inside the ng-container.

The content cell use the standard Angular syntax. {{property}}. Angular automatically understand that one item of the addresses array should take the name "element"

At the end

Finally to add some style, inside the addresses.component.less set the width to 100%

table {
    width: 100%;
}

The result

Now the result should be something like this:

mat-table


Last modified on: February 17, 2020