Angular 2 application with asp.net core API – Part 2

angular

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

<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>

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

<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>

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;
}

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";
import { HttpModule } from "@angular/http";
import { RouterModule } from "@angular/router";
import {Location } from "@angular/common";
import { AppComponent } from "./components/app/app.component";
import { NavMenuComponent } from "./components/navmenu/navmenu.component";
import { HomeComponent } from "./components/home/home.component";
import { FetchDataComponent } from "./components/fetchdata/fetchdata.component";
import { CounterComponent } from "./components/counter/counter.component";
import { TodoComponent } from "./components/todo/todo.component";
import { TodoitemComponent } from "./components/todoitem/todoitem.component";
import { TodoService } from "./components/service/Todo.service";
import { LoggerService } from "./components/service/logger.service";
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
CounterComponent,
FetchDataComponent,
TodoComponent,
TodoitemComponent,
HomeComponent
],
imports: [
CommonModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
{ path: "", redirectTo: "home", pathMatch: "full" },
{ path: "home", component: HomeComponent },
{ path: "counter", component: CounterComponent },
{ path: "fetch-data", component: FetchDataComponent },
{ path: "todo", component: TodoComponent },
{ path: "todo/:id", component: TodoitemComponent },
{ path: "**", redirectTo: "home" }
])
],
providers: [
LoggerService,
TodoService
]
})
export class AppModuleShared {
}

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.

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

Published by Gadael Sedubun

Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: