The angular template from dotnet cli is using the angular v4.4.6 LTS version. So we cannot use the latest angular v.5 APIs. After creating the angular components in earlier post now we need to write each component, if you use VSCode or Visual Studio this will be easy because the editor will provide intellisense for typescript syntax. Inside todo.components.ts, create a class named TodoComponent and decorate it with @Component to indicate the class as a component also it’s selector and a templateUrl. As for the template file todo.component.html, simply put an input text and a button then hook it up with the method inside the component. See the full code below.
Angular Component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Todo </h1> | |
<p>This component is to run todo app.</p> | |
<p *ngIf="!todos"><em>Loading…</em></p> | |
<div class="col-md-3 input-group"> | |
<!– <label>New todo | |
</label> –> | |
<input [(ngModel)]="todo.title" class="form-control" placeholder="New todo title."> | |
<span class="input-group-btn"> | |
<button (click)="newtodo()" class="btn btn-primary">Submit</button> | |
</span> | |
</div> | |
<table class='table' *ngIf="todos"> | |
<thead> | |
<tr> | |
<th>Title</th> | |
<th># Items</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr *ngFor="let todo of todos"> | |
<td><a routerLink="/todo/{{todo.id}}"> {{ todo.title }}</a></td> | |
<td>{{ todo.totalItem }}</td> | |
</tr> | |
</tbody> | |
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, Inject } from "@angular/core"; | |
import { Http } from "@angular/http"; | |
import { ITodoItem } from "../todoitem/todoitem.component"; | |
import { TodoService } from "../service/Todo.service"; | |
@Component({ | |
selector: "todo", | |
templateUrl: "./todo.component.html" | |
}) | |
export class TodoComponent { | |
public todos: ITodo[] = []; | |
public todo: ITodo = {title:"" ,id:0, TotalItem:0 }; | |
constructor(private Todoservice: TodoService) { | |
this.getTodo(); | |
} | |
initempty(): void { | |
this.todo = {title:"" ,id:0, TotalItem:0 }; | |
} | |
getTodo(): void { | |
this.Todoservice.getTodo().subscribe(result => { this.todos = result.json() as ITodo[]; }, error => { | |
console.log(error); | |
}); | |
} | |
newtodo(): void { | |
if(this.todo.title !== "") { | |
const data: ITodo = this.Todoservice.addtodo(this.todo); | |
this.getTodo(); | |
console.log(data); | |
this.initempty(); | |
} | |
} | |
} | |
export interface ITodo { | |
title: string; | |
id: number; | |
TotalItem: number; | |
} |
Do the same thing with todoitem.component.ts, only for this one we need to add an Angular ActivatedRoute as dependency in it’s constructor. We need the angular ActivatedRoute to be able to read the route parameter, in this component the parameter is [id]. The parameter was registered when we declare a router inside app.shared.module.ts, this file is responsible for registering all components, services and modules that will be used in our angular clientapp(generated by dotnet cli). Here is the snipped code for todoitem.component.ts and app.shares.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Todo item {{ todo.id }} </h1> | |
<p>Edit item {{ todo.title }}.</p> | |
<p *ngIf="!todo"><em>Loading…</em></p> | |
<!– <label>item: </label> –> | |
<div class="col-md-3 input-group"> | |
<input [(ngModel)]="todoitem.item" class="form-control " placeholder="new todo item"/> | |
<span class="input-group-btn"> | |
<button (click)="Additem()" class="btn btn-primary " >Add</button> | |
</span> | |
</div> | |
<table class='table' *ngIf="todoItems"> | |
<thead> | |
<tr> | |
<th>ID</th> | |
<th>Item</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr *ngFor="let todoitem of todoItems"> | |
<td>{{ todoitem.id }}</td> | |
<td>{{ todoitem.item }}</td> | |
</tr> | |
</tbody> | |
</table> | |
<button (click)="goback()" class="btn-default btn">back</button> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, Inject } from "@angular/core"; | |
import { Http } from "@angular/http"; | |
import { ITodo } from "../todo/todo.component"; | |
import { ActivatedRoute } from "@angular/router"; | |
import { Location } from "@angular/common"; | |
import { TodoService } from "../service/Todo.service"; | |
@Component({ | |
selector: "todoitem", | |
templateUrl: "./todoitem.component.html" | |
}) | |
export class TodoitemComponent { | |
public todo: ITodo = { id:0, title:"", TotalItem:0}; | |
public todoId: number = 0; | |
public todoitem: ITodoItem = { item:"", id:0 }; | |
public todoItems: ITodoItem[] = []; | |
constructor(private todoservice: TodoService, private route: ActivatedRoute,private location: Location) { | |
const id : any = this.route.snapshot.paramMap.get("id"); | |
if(id!==null) { | |
this.todoId=parseInt(id, undefined); | |
this.loadData(); | |
} | |
} | |
Additem(): void { | |
this.todoservice.Additem(this.todoitem, this.todoId).subscribe(result => { | |
this.loadData(); | |
this.initempty(); | |
}, error => { | |
console.log(error); | |
}); | |
} | |
initempty(): void { | |
this.todoitem = {item:"" ,id:0}; | |
} | |
loadData(): void { | |
this.todoservice.getTodoById(this.todoId).subscribe(result => { | |
this.todo= result.json() as ITodo; | |
}, error => { | |
console.log(error); | |
}); | |
this.todoservice.getTodoItem(this.todoId).subscribe(result => { | |
this.todoItems = result.json() as ITodoItem[]; | |
},error => { | |
console.error(error); | |
}); | |
} | |
goback(): void { | |
this.location.back(); | |
} | |
} | |
export interface ITodoItem { | |
item: string; | |
id: number; | |
} |
Inside each components you will see that i also create an interface as a datatype for each component, the purpose is for us to have a typed reference when creating an object or variable or etc. Note that this is why we use TypeScript instead of JavaScript, to help developer by providing a typed structure while developing angular application.
Angular Service
Both components also depend on a service class called TodoService, in angular, services are a great way to share information among classes (components) that don’t know each other. Before creating TodoService class, make a folder called service inside ClientApp/app/components/ then create a file Todo.service.ts inside it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Http, RequestOptionsArgs, RequestOptions, Headers} from "@angular/http"; | |
import { Component, Injectable, Inject } from "@angular/core"; | |
import { LoggerService } from "./logger.service"; | |
import { ITodo } from "../todo/todo.component"; | |
import { ITodoItem } from "../todoitem/todoitem.component"; | |
import { Subscription } from "rxjs/Subscription"; | |
import { IfObservable } from "rxjs/observable/IfObservable"; | |
@Injectable() | |
export class TodoService { | |
addtodo(arg0: any): ITodo { | |
var posted: ITodo = {id:0, title:"", TotalItem:0}; | |
this.http.post(this.BASE_URL+"api/todo/Addtodo", JSON.stringify(arg0), this.opt) | |
.subscribe(result => { | |
posted= result.json() as ITodo; | |
}, error => { | |
console.log(error); | |
}); | |
return posted; | |
} | |
private opt: RequestOptions = new RequestOptions({ | |
headers: new Headers({"content-type":"application/json"}) | |
}); | |
constructor(private http: Http, private logger: LoggerService, @Inject("BASE_URL") private BASE_URL: string) { | |
} | |
getTodoItem(todoId: number) { | |
return this.http.get(this.BASE_URL + "api/todo/getitem?todoId="+todoId); | |
} | |
getTodo() { | |
return this.http.get(this.BASE_URL + "api/todo/index"); | |
} | |
getTodoById(todoId: number) { | |
return this.http.get(this.BASE_URL + "api/todo/get?id="+todoId); | |
} | |
Additem(todoitem: ITodoItem,todoId: number) { | |
return this.http.post(this.BASE_URL + "api/todo/Additem?id="+todoId, JSON.stringify(todoitem), this.opt); | |
} | |
} |
Dont forget to register todoservice inside app.shared.module.ts, put it in a providers[] decoration (see app.shared.module.ts code above).
And that’s it the app is ready and can be tested on your local machine.
Source Code