Adding the Angular components

In this section, we will create custom components using TypeScript and create a root app folder inside our Web App project.

Under app folder, we will create another folder known as shared and this is where we will create some common components which will be used throughout the application:

Creating a Message component

This component will be used to show messages on the screen when the user performs any action. These messages will be success, error or warning messages displayed in the browser.

First, we create MessageModel, which takes the type and msg parameters in a parameterized constructor and can be passed to MessageService to push messages in an array.

Create a file, message.service.ts, in the app > shared > message folder, and place the following code:

    export class MessageModel { 

type: string;
msg: string;

constructor(type: string, message: string) {
if (type == 'E')
type = 'danger';
else if (type == 'S')
type = 'success';

this.type = type;
this.msg = message;
}
}

Creating HTTP client component

This component is a wrapper of the Angular http module and can be used to send RESTful messages to our service layer.

Add http-client.service.ts under the app > shared > httpclient folder, and add the following code:

    import {Injectable, Inject} from '@angular/core'; 
import {Http, Headers, RequestOptions, Response} from
'@angular/http';
import { Observable } from 'rxjs/Observable';
import { APP_CONFIG, AppConfig } from '../../app.config';

@Injectable()
export class HttpClient {
options;
headers;
apiEndpoint: string;

constructor(private http: Http,
@Inject(APP_CONFIG) config: AppConfig) {
this.apiEndpoint = config.apiEndpoint;
}
get(url) {
this.headers = new Headers({ 'Content-Type':
'application/json'
});

this.options = new RequestOptions({ headers:
this.headers });
return this.http.get(this.apiEndpoint + url);
}

post(url, data) {
this.headers = new Headers({ 'Content-Type':
'application/json' });
this.options = new RequestOptions({ headers:
this.headers });
let options = new RequestOptions({ headers:
this.headers, });
return this.http.post(this.apiEndpoint + url,
data, options);
}
}

Adding service request View Model

Next, we will add our View Model, to which the form controls will bind. Add the data-models.interface.ts file in app > shared > models, and add the following code:

    export class ServiceRequest { 
id: number;
tenantID: number;
description: string;
employeeComments: string;
statusId: number;
}

We can add as many models as required under this file.

Adding a shared module

In Angular, you can define modules; this helps to keep components, providers, and other resources under one module. We can refer other modules using imports, as shown next, and export components, using the exports key. Here, we create a shared module to keep our MessageComponent and our custom HTTP client service in one place and then we refer this module in other modules to leverage these features:

    import { NgModule }       from '@angular/core'; 
import { CommonModule } from '@angular/common';
import { MessageComponent } from './message/message.component';
import { HttpClient } from './httpclient/http-client.service';
import { MessageService } from './message/message.service';
import { Http, HttpModule } from '@angular/http';

@NgModule({
imports: [
CommonModule,
HttpModule
],
exports: [
MessageComponent
],
declarations: [
MessageComponent
],
providers: [
MessageService,
HttpClient
]
})

export class SharedModule {
}

Adding configuration settings

In our application, we will be making RESTful calls to our service layer and specifying the base service URL, authentication server (CAS) URL, or other attributes, in one place. So, let's add the app.config.ts file in the app folder and specify the following code:

    import { OpaqueToken } from '@angular/core'; 

export let APP_CONFIG = new OpaqueToken('app.config');

export interface AppConfig {
apiEndpoint: string;
title: string;
casEndPoint: string;
appEndPoint: string;
}

export const TMS_DI_CONFIG: AppConfig = {
apiEndpoint: 'http://localhost:5001/api/',
title: 'TMS System',
casEndPoint: 'http://localhost:5001',
appEndPoint: 'http://localhost:5050'
};

Adding Application module

This is our main Application module, which contains the ServiceRequest component. We can create domain-specific modules depending on the application size. Here, we also refer the SharedModule, which we created earlier, so that we can access our custom HTTP client service and MessageComponent:

    import { NgModule }      from '@angular/core'; 
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF } from '@angular/common';
import { AppComponent } from './app.component';
import {MenuComponent} from './menu.component';
import { routing } from './app.routes';
import { ServiceRequestComponent } from './components/
tenant/service-request.component';
import { SharedModule } from './shared/shared.module';
import { APP_CONFIG, TMS_DI_CONFIG } from './app.config';
import {FormsModule} from '@angular/forms';
import {ServiceRequestService} from './components/tenant/
service-request.service';

@NgModule({
imports: [
BrowserModule,
routing,
SharedModule,
FormsModule
],
declarations: [
AppComponent,
ServiceRequestComponent,
MenuComponent
],
bootstrap: [AppComponent],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: APP_CONFIG, useValue: TMS_DI_CONFIG },
ServiceRequestService
]
})
export class AppModule { }

Configuring Angular Routes

To configure routing, we will create app.routes.ts under the app folder and add the following code:

    import { ModuleWithProviders }  from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router';
import { ServiceRequestComponent } from './components/
tenant/service-request.component'
import { MenuComponent } from './menu.component'

//Routes Configuration
export const routes: Routes = [
{ path: 'createServiceRequest', component:
ServiceRequestComponent },
{ path: 'menu', component: MenuComponent },
{
path: '',
redirectTo: '/menu',
pathMatch: 'full'
},
];

export const routing: ModuleWithProviders =
RouterModule.forRoot(routes);

Adding App component

App component is the main component, which hooks up with the main Angular app. Here, tenant-mgmt is the main selector, which loads the Feature/Index page. This selector will be added in the Home/Index page.

    import { Component } from '@angular/core'; 

@Component({
selector: 'tenant-mgmt',
templateUrl: 'Feature/Index'
})
export class AppComponent {
}

Adding Menu component

To load menus, we have to create a separate file, menu.component.ts, in the app folder and load the Feature/Menu, page as follows:

    import { Component, AfterViewInit } from '@angular/core'; 
import { Router } from '@angular/router';
@Component({
selector: 'menu',
templateUrl: 'Feature/Menu'
})
export class MenuComponent {

}

Adding Main module

The Main.ts bootstraps the Main Application module; the code is given as follows:

    import { platformBrowserDynamic } from 
'@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Adding domain-specific components

For each business domain, we will create a service class and a component class. The service class will be responsible for making all the HTTP calls to the service layer, whereas the component class will be responsible for model binding and using the service class to submit or receive data.

Here is the implementation of the service class as discussed:

    import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch';
import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '../../shared/httpclient/
http-client.service';
import {Response} from '@angular/http';
import { ServiceRequest } from '../../shared/models/
data-models.interface';

@Injectable()
export class ServiceRequestService {

constructor(private httpClient: HttpClient) { }

getServiceRequest(id: any): Observable<ServiceRequest> {
return this.httpClient.get('serviceRequest?id=' + id)
.map(this.extractData)
.catch(this.handleError);
}

getAllServiceRequests(): Observable<ServiceRequest[]> {
return this.httpClient.get('serviceRequest')
.map(this.extractData)
.catch(this.handleError);
}

postServiceRequest(serviceRequest: any):
Observable<ServiceRequest> {
let body = JSON.stringify(ServiceRequest);
return this.httpClient.post('serviceRequest/post', body)
.map(this.extractData)
.catch(this.handleError);
}

private extractData(res: Response) {
let body = res.json();
return body || {};
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? &grave;${error.status} -
${error.statusText}&grave; :'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}

}

Following is the implementation of the ServiceRequest component, which calls the service class as discussed earlier:

    import { Component } from '@angular/core'; 
import { ServiceRequest } from '../../shared/models/
data-models.interface';
import { MessageService, MessageModel } from '../../shared/
message/message.service';
import { ServiceRequestService } from './service-request.service';

@Component
({
selector: 'createServiceRequest',
templateUrl: 'Tenant/Create'
})

export class ServiceRequestComponent {

serviceRequest: ServiceRequest;
disable = false;
serviceRequestService: ServiceRequestService;
message: MessageService;

constructor(messageService: MessageService,
serviceRequestService: ServiceRequestService
) {
this.message = messageService;
this.serviceRequestService = serviceRequestService;
messageService.clearMessages();
this.serviceRequest = new ServiceRequest();
}

onSubmit() {
this.serviceRequestService.postServiceRequest(
this.serviceRequest)
.subscribe(() => {
serviceReq =>
this.message.pushMessage(new MessageModel('success',
'Service Request Submitted Successfully'));
},
error => {
this.message.pushMessage(new MessageModel(
'danger', 'Failed to submit ' + error));
});
}
}

Adding SystemJS config file to Bootstrap Angular

We will now add a custom systemjs.config.js file in the wwwroot/app folder, which tells our System loader to load the Main.js file (generated from Main.ts):

    (function (global) { 
System.config({
paths: {
// paths serve as alias
'npm:': './lib/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles
/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles
/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/
platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/
platform-browser-dynamic/bundles/
platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles
/router.umd.js',
'@angular/router/upgrade': 'npm:@angular/router/
bundles/router-upgrade.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles
/forms.umd.js',
'@angular/upgrade': 'npm:@angular/upgrade/
bundles/upgrade.umd.js',
'@angular/upgrade/static': 'npm:@angular/upgrade/
bundles/upgrade-static.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-
web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no
filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);

Next, we create another importer.js file under the wwwroot/app folder and call System.import to load our Main module.

    System.import('app/main').catch(function (err) { 
console.error(err);
});

Lastly, we will just add the following script references in our _Layout.cshtml file residing in the Views/Shared folder:

     <script src="~/lib/core-js/shim.min.js"></script> 
<script src="~/lib/zone.js/zone.js"></script>
<script src="~/lib/reflect-metadata/Reflect.js"></script>
<script src="~/lib/systemjs/system.src.js"></script>
<script src="~/lib/rxjs/bundles/Rx.js"></script>
<script src="~/app/systemjs.config.js"></script>
<script src="~/app/importer.js"></script>

So, when our application starts, our Layout page loads the systemjs.config.js and importer.js. This importer.js loads the Main.js file and bootstraps our main AppModule, which we created earlier. This AppModule bootstraps our AppComponent, which is our main application component and displays the Feature/Index page, where the tenant-mgmt selector is defined.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.36.71