A TODO list app created in Angular 2 angular 4 and beyond. C
If you have not install or setup, please follow the instruction Running First Angular app.

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

This chapter we explore,

  1. how you register an application with angular
  2. how you can easily create a Friday’s todo list
  3. how you can do the binding and its conditioning in angular

We will create a listing page for Friday’s todo.

 
 

You can add new record.

  

 

…and view existing record to update it or delete.

  


The final functioning plunk should be like this.


How you register an application with angular?


The first thing we will look at is the module component file.
app/app.module.ts


import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';
import { HttpModule }    from '@angular/http';  

import { AppComponent } from './app.component'; 
@NgModule({ ... })
export class AppModule { }

Here you will see the common imports and format to start a simple module app which we load from angular library.

 
@NgModule({
  imports: [    BrowserModule,    FormsModule,    HttpModule   ],
  declarations: [    AppComponent   ],
  providers: [   ],
  bootstrap: [ AppComponent ]
})

Then, we go into attributes imports,declarations, providers and bootstrap
.
The ‘imports’ primarily defines the module-level items we are importing.
Use ‘declarations’ to mention all the components we are declaring and using.
Utilize ‘providers’ for registering services [we will see in part2]
With ‘bootstrap’ we are defining the first application component entry point to load.

**Components is usually the subset of a module. A module can have many components.

The next thing we will look at is the controller component
app/app.component.ts


  selector: 'footer-section', //used for reference identifier
  templateUrl: './app.component.html', // the html to include for this component
  styleUrls: ['./app.component.css'] // the css file we are importing.

The selector is used to be referenced in another html place later on. This will be very useful later on for modular development to assemble and resuse parts like lego block. Example usage..


<body> 
<footer-section> </footer-section>
</body]>

The templateUrl tell the current component controller to point to which html file to render.
The styleUrls will import css for the component html. A square bracket [] indicates possible multiple values. Example


  ['./app.component.css','./more.component.css','./extra.component.css']

We want to create a single component at moment.

This component will have three modes – a listing page, a details page for existing record, a details page for new record. So we will have userMode with 3 possible values. With userMode , we will show hide the section accordingly.


   private userMode: string = 'LISTING';  //'LISTING' or 'DETAILS-EXISTING' or 'DETAILS-NEW'

Next, we will define the data structure for the todo activity. It is a simple class with property of description and identifier.

 
class FridayActivity {   
  private id: number;
  private activityName: string;
}

Next, we allow initialization with parameters for the class construction.

 
  constructor(id: number, activityName: string) {
    this.id = id;
    this.activityName = activityName;
  } 

Since we know we have a listing and details item, we can define them with reference to our class. This will be very convenient for us to reference them again later throughout the controller.

 
  private fridayActivityList: FridayActivity[] = []; // for a list
  private userSelectedActivity: FridayActivity; //for a selected item details

Let’s initialize the list with some list of activity data.

 
  ngOnInit(): void {
    this.initializeList();
  }

   initializeList(): void {
    //instantiate activity items
    const drinkingActivity = new FridayActivity(1, 'Pub and Bar Gathering');
    const movieActivity = new FridayActivity(2, 'Movie Night');
    const diningActivity = new FridayActivity(3, 'Romantic Dining');

  //append each item into list
    this.fridayActivityList.push(drinkingActivity);
    this.fridayActivityList.push(movieActivity);
    this.fridayActivityList.push(diningActivity);
  }

Since our screen will have different pages like listing and details , there should be method to redirect to 3 userMode mentioned earlier.
We can manage it by setting its data state and then evaluating them in the html later through binding.

From a listing to a detail page, we pass in parameter of which option activity user selected.

  
  redirectListing(){ 
    this.userMode = 'LISTING'; 
  }
  redirectChooseActivity(_userSelectedActivity: FridayActivity) { 
    this.userMode = 'DETAILS-EXISTING';
  }

  redirectAddActivity( _userSelectedActivity: FridayActivity ) {  
    this.userMode = 'DETAILS-NEW';
  }

In cases where we redirect user to add new activity, we cannot pass in any valid option as parameter, so you will need create a new instance and generate the latest id for it.

  
  redirectAddActivity( _userSelectedActivity: FridayActivity ) { 
    const currentIndex  = this.fridayActivityList.length + 2; 
    this.userSelectedActivity = new FridayActivity( currentIndex,  '' ); 
    this.userMode = 'DETAILS-NEW';
  } 

When we redirect user to existing activity we will need pass the current selected activity instance and assign our user’s current selection into this.userSelectedActivity of the current item object details.

  
  redirectChooseActivity(_userSelectedActivity: FridayActivity) {
    this.userSelectedActivity = _userSelectedActivity;
    console.log( this.userSelectedActivity );
    this.userMode = 'DETAILS-EXISTING';
  }

Now we will look at the html file.

app.component.html

   
 <div [class.hidden]="userMode!== 'LISTING' " >
        listing here
 </div >  
 <div [class.hidden]="  
         userMode!== 'DETAILS-EXISTING' && userMode!== 'DETAILS-NEW' " 
         *ngIf="userSelectedActivity" >  
        details here
 </div > 

In angular html binding, to link a click event, we use (click) to explicit define an method binding action event. In plain javascript, we use event like onclick.

 
 <div > 
 a (click)="doSomethingDefinedInComponentTs()"
</div >  

To bind an attribute we use [attrName]

 
 <div > 
 a [class.is-red-color]="isBooleanExpressionDefinedInComponentTs"
  [data-id-value]="isPropertyExpressionDefinedInComponentTs"
</div >  

So, we want to hide our userMode, when not correct mode accordingly.

   
[class.hidden]="userMode!== 'LISTING' " ----> show only when listing mode

[class.hidden]=" userMode!== 'DETAILS-EXISTING' && userMode!== 'DETAILS-NEW' "   -------> show only when details mode

To ensure the class is effective, we will add it in our app.component.css

  
.hidden{
  display:none !important;
}

Then, we use *ngIf purposely to show and create html block only when there is a selected activity by user. This prevent errors that render data content invalidly and also reduce bloat in html chunk codes.

   
*ngIf="userSelectedActivity"

To list a repeated iteration of record we use *ngFor.

   
*ngFor="let item of itemList"

In our case, we want to allow user to redirect to existing details page when any item clicked.
When they click the add new button, we will redirect to a new page using our function method define before.

   
    <ol>
        <li *ngFor="let activity of fridayActivityList">
            <a (click)="redirectChooseActivity(activity)"> {{activity.activityName }}</a>
        </li>
    </ol>

         <p>   <button (click)="redirectAddActivity(  )">Add new Record</button></p> 

Then in our details html,
i) we want to bind data from current selected activity.
ii) we also want to allow user perform actual Add, Update and Delete operation.

   
   
<div [class.hidden]="  userMode!== 'DETAILS-EXISTING' && userMode!== 'DETAILS-NEW' " *ngIf="userSelectedActivity">  
         <p>   <button class="" (click)="redirectListing( )">Back</button></p> 
      
        <p>  Activity Name</p>
        <p>  <input type="text" [(ngModel)]="userSelectedActivity.activityName"/></p>
        
         <p  [class.hidden]="userMode!== 'DETAILS-EXISTING'   ">  
         <button (click)="performDelete( )">Delete</button>
        <button (click)="performUpdate( )">Update</button>
        </p>
        
         <p  [class.hidden]="  userMode!== 'DETAILS-NEW' ">  
         <button (click)="performAdd(  )">Add</button> 
        </p> 
     
</div> 

To get two way binding, we use [(ngModel)] to know what user keyed in and to display value from data controller. Single binding is [], two way ngModel utilizes attribute and method binding. We will bind it to the attribute we defined earlier.

   
 [(ngModel)]="userSelectedActivity.activityName"

Next ,we will bind a followup action to perform the operation.

     
          <button (click)="performAdd(  )"> Add</button>  
          <button (click)="performDelete( )"> Delete</button> 
         <button (click)="performUpdate( )"> Update</button> 

After that, we define the function in our component controller file.
The activity is done using some common ES6.
Be sure to activate polyfills in your angular-cli project, polyfill.ts or any webpack or setup equivalent.
Feel free to read some information on es6 and list manipulation here.

     
performAdd() { 
    this.fridayActivityList.push(this.userSelectedActivity);
    this.redirectListing(); 
}

performDelete() {
    this.fridayActivityList = this.fridayActivityList.filter((itemActivity) => { return itemActivity && itemActivity.id != this.userSelectedActivity.id })
    this.redirectListing();
}

performUpdate() {
    const indexItem = this.fridayActivityList.findIndex((itemActivity) => {
        return itemActivity.id === this.userSelectedActivity.id 
    })

    this.fridayActivityList[indexItem] = this.userSelectedActivity;
    this.redirectListing();

}

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


If you like please share this and comment and subscribe.

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 *