This is a 4 series to help you kickstart your coding in angular 4.

  1. Code Angular – Basic Series- Part 1
  2. Code Angular – Basic Series- Part 2
  3. Code Angular – Basic Series- Part 3
  4. Code Angular – Basic Series- Part 4

In series 2, we explore,

  1. how you can split your content into components/parts in coding.
  2. how you control the routing of component/pages
  3. how you retain data when you change routing and component interaction



1) How you can split your content into components/part?
Open file app/app.module.ts



import { AppComponent } from './app.component'; 
...
..
.
  declarations: [
    AppComponent 
  ],

You will notice that we previously do every code in 1 single file.
That would not be a scaleable code and hard to reuse and difficult to maintain for test cases and tracking issues.

We want to split our code like the diagram.



Then let’s create and declare 2 more component – list component and details component.



import { AppComponent } from './app.component'; 
import { ListComponent } from './list.component'; 
import { DetailsComponent } from './details.component'; 
...
..
.
  declarations: [
    AppComponent ,
    ListComponent ,DetailsComponent 
  ],

Now we must create the files declared above with its html and controller ts.
app/details.component.html
app/details.component.ts
app/list.component.html
app/list.component.ts

So we begin by copying the html chunk and controller ts part into its relevant component html file.
app/list.component.html


 <!--Listing here-->  
<!--START LISTING-->  

    <ol> 
        <li *ngFor="let activity of fridayActivityList"> 
            <a (click)="redirectChooseActivity(activity)"  [routerLink]="['/details',  'EXISTING',  activity.id]" >  {{activity.activityName }}</a> 
            
        </li> 
    </ol> 

     <p>    <button  [routerLink]="['/details',  'NEW',   '']"  > Add new Record</button> </p>  
      
<!--END LISTING--> 

app/details.component.html

 <!--START DETAILS-->
<div *ngIf="userSelectedActivity">
    <p> <button   [routerLink]="['/list' ]" >Back</button></p>

    <p> Activity Name</p>
    <p> <input type="text" [(ngModel)]="userSelectedActivity.activityName" /></p>

    <p [class.hidden]="userMode!== 'EXISTING'   ">
        <button (click)="performDelete( userSelectedActivity )">Delete</button>
        <button (click)="performUpdate(userSelectedActivity )">Update</button>
    </p>

    <p [class.hidden]="  userMode!== 'NEW' ">
        <button (click)="performAdd(userSelectedActivity  )">Add</button>
    </p>

</div>

<!--END DETAILS-->

app/list.component.ts

 
@Component({
  selector: 'friday-list',
  templateUrl: './list.component.html',
  styleUrls: ['./app.component.css']
})
export class ListComponent {
  title = 'Manage your Friday Activity';
  private fridayActivityList: FridayActivity[] = [];
  private userSelectedActivity: FridayActivity;  
  ngOnInit(): void { this.initializeList(); } 
  redirectChooseActivity(_userSelectedActivity: FridayActivity) {  } 
  initializeList(): void {   }

}

app/details.component.ts

  
@Component({
    selector: 'friday-details',
    templateUrl: './details.component.html',
    styleUrls: ['./app.component.css']
})
export class DetailsComponent { 
   ...
    ngOnInit(): void {   } 
    redirectListingPage(){    }
    performAdd(_fridayActivity: FridayActivity) {  } 
    performDelete(_fridayActivity: FridayActivity) {   } 
    performUpdate(_fridayActivity: FridayActivity) {   } 
    initializeUrlParam() {   }
}

Also, we will create a separate class for file app/class/FridayActivity.ts


//export so other can import and reuse
export class FridayActivity {
  ...
} 

At this point you probably notice, uh-oh, we previously had a userSelectedActivity defined in app.component.ts. Now if we have two separated list and details component, how to share the data across them? and how will the two component interact with each other?

For this case, we need to use a service that gels and connect the data communication between them.
Let’s create a DataService then.

**

We are using singleton concept on the service to ensure 1 single instance of singleton state persist throughout the current app lifecyle. In this way, the data state declared is cached. This data state can also be set and get.

**

DataService will function like a caching service for convenience of one component to set/save the value and then another component can retrieve/get that saved value.

To understand this, first we need understand at higher level, our routing case and action involve in saving its data and retrieving data.


 

When route from app to list
1) Route do redirect load list component.
2) List component will create some dummy data first time and set into DataService. When list data already exist, it will fetch instead from DataService.

When route from list to details
1) List will set user’s selected data into DataService.
2) List component will redirect to details component.
3) Details will retrieve get the selected activitiy.

When route from details to list
1) Details will set user’s selected data into DataService list depending on save,update, or delete.
2) Details component will redirect to list component.
3) List will retrieve the modified list.


Open file app/app.module.ts


import { DataService } from './data.service';
...
..
.
providers: [  DataService ],

Then create the file app/data.service.ts with a the template below.


import { Injectable } from '@angular/core';
import { FridayActivity } from './class/FridayActivity';   

@Injectable()
export class DataService {
  private yourDataItem:string;
  public getYourDataItem(){return this.yourDataItem;}
  public setYourDataItem(yourDataItem){ this.yourDataItem = yourDataItem;}

}

For our real case we are going to import our previous data definition.


import { Injectable } from '@angular/core';
import { FridayActivity } from './class/FridayActivity';   

@Injectable()
export class DataService {
  
    private fridayActivityList: FridayActivity[] = []; 
    private fridayActivityItem: FridayActivity;
   ...
//getter and setter for fridayActivityList
//getter and setter for fridayActivityItem
...

    public performAdd(_fridayActivity: FridayActivity) { ...  } 
    public performDelete(_fridayActivity: FridayActivity) {...   } 
    public performUpdate(_fridayActivity: FridayActivity) { ...  } 
}

So how do you import DataService into your component list and details? Using Dependency Injection.
list.component.ts


import { DataService } from './data.service'; 
@Component({  ... })
export class ListComponent { 
  constructor(private dataService: DataService) { } 
} 

details.component.ts


import { DataService } from './data.service'; 
@Component({  ... })
export class DetailsComponent{ 
  constructor(private dataService: DataService) { } 
} 

**That’s it! Dependency injection is very useful to pass instantiated reference in lifecycle of app across different components. You can use it without needing to keep re instantiating. constructing it. As such, we can have convenience in accessing this reference data


Next question , how do we control the routing of listing and page?

First we create file app/app-routing.module.ts

 
import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; 
import { DetailsComponent }   from './details.component'; //import details component
import { ListComponent }      from './list.component'; //import list component

const routes: Routes = [
  { path: '', redirectTo: '/list', pathMatch: 'full' },//defaults to list
  { path: 'list',  component: ListComponent },//points to imported list component
  { path: 'details/:mode/:id', component: DetailsComponent } //points to imported DetailsComponent with 2 parameters mode and id  
];

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

Then, we declare it in the module

 
import { AppRoutingModule } from './app-routing.module'; 
@NgModule({   ...

  imports: [ 
    AppRoutingModule
  ] ...
 })
export class DetailsComponent{ 
  constructor(private dataService: DataService) { } 
}  

In our file app.component.html, add a router-outlet tag to allow loading content be rendered in that placeholder tag. Most of these definitions are provided by Angular. Always make sure to refer the official doc for syntax and accuracy.

 
 <!--start content-->  
 <router-outlet>   </router-outlet>  
 <!--end content-->  

Essentially there will only be two way to trigger sending link creation the route.
First, via the html file.
Second way, via the controller component ts file.

In our html file, app.component.html we want a link to details route.
We give it 2 parameters the mode and activitid.
So in total, we need to pass in 3 parameters – route name, mode, activity id

 
   <a   [routerLink]="['/details',  'EXISTING',  activity.id]" >  redirect to details </a>  
 

In controller component, ts, we can write programmatic code for redirection like this.

  
      this.router.navigate(['/details', {'mode':'', id:'' }]);
 

After redirection, we need to be able to code component to receive route parameters. The code look like this in details.component.ts

  
      this.route.paramMap
            .switchMap((params: ParamMap) => {
                const id = +params.get('id');
                const userMode = params.get('mode');
                const userSelectedActivity = this.dataService.getActivityFromId(id);
                let result = []; 
                result['userSelectedActivity'] = userSelectedActivity
                result['userMode'] = userMode 
                return result;
            }).subscribe((result) => {
                console.log('result', result);
            });
 

The pre-requisite is to import again the default router from @angular library..

  
import { Router } from '@angular/router';
@Component({...  })
export class DetailsComponent { 
    constructor(   private router: Router  ) { ...} 
    initializeUrlParam() {   this.route //access}
}
 

By now , you would have realized, “hey! most things are readily available out of box by Angular library!” You are correct.


To continue next:
Code Angular – Basic Series- Part 3


If you like please share this and comment and subscribe. Feel free to ask any questions or corrections too.

Success is no accident. It is hard work, perseverance, learning, studying, sacrifice and most of all, love of what you are doing or learning to do, Pele

Leave a Reply

Your email address will not be published. Required fields are marked *