1 / 65

Understanding Services & Dependency Injection in Angular 2

Learn how to create and consume RESTful APIs in a single page application using Angular 2, including routing, pipes, and unit testing.

lpate
Download Presentation

Understanding Services & Dependency Injection in Angular 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Day 3 Understanding Services Dependency Injection Creating and Consuming REST API Single Page Application – Routing Pipes Unit Testing Introduction

  2. Angular2 Services • Components are responsible for displaying stuff. • Need of Service: • If the logic or data isn’t view specific OR • Needs to be used globally across number of different components • We need services. • Service is basically just a class

  3. Hands On Example • Create app.services.ts file in src folder import {User} from "./app.models";export class AppService {usersData:User[]; constructor(){ this.usersData = [new User("UF1", "UL1"), new User("UF2", "UL2"), new User("UF3", "UL3")]; }getAllUsers() { return this.usersData; }}

  4. Using Service • Create an object of Service • Invoke the method of a service. Modify AppComponent Constructor constructor(){ let a:AppService = new AppService(); this.users = a.getAllUsers();} • Here, service object is for AppComponent. • It’s not a global object

  5. Dependency Injection • Features of Services: • Are independent from any particular component • Provide shared data or logic across components • Dependency Injection is a pattern in which a class receives the instances of objects it needs (called dependencies) from an external source rather than creating them itself. • Angular is designed to manage all these dependencies between components and services for us. • Alternatively, we can register our service with Angular2 and Angular creates single instance of that class called Singleton • Angular2 provides an built-in Injector, which maintains a container of the created service instances.

  6. Working with Service • 1) A class with @Injectable to tell angular 2 that its to be injected – DataService • 2) A class with a constructor that accepts a type to be injected import {Component, Injectable} from “@angular/core“ @Injectable() export class AppService { }

  7. Hands On Example • Inject the dependency object in any component as argument. • Modify AppComponent Constructor constructor(private asvc: AppService){//let a:AppService = new AppService();this.users = asvc.getAllUsers();} • Register the Service in our application module by using providers metadata attribute. • providers: [AppService],

  8. Server Communication with REST REST stands for Representational State Transfer • It is an architectural pattern for developing web services. • REST web services communicate over the HTTP specification, using HTTP vocabulary. • GET to retrieve information • POST to add new information, showing its relation to old information • PUT to update information • DELETE to discard information

  9. MongoDB – NoSQL Database • NoSQL databases, don't use the traditional table-oriented SQL. • MongoDB is a document-oriented database that which stores data in documents, which are data structures that are almost identical to the standard JSON objects. • Collections == tables • Documents == record • Download from mongodb.com • After installation add the path to the MongoDB executable (usually the Program Files folder) to your environment variables . • Verify from command prompt > mongod

  10. Creating REST Api • Deploydis a tool for modeling APIs for web applications. • It is built on top of Node.js and MongoDB, which allows it to store data as JSON. • Install Deployd tool using npm i.e. npmi –g deployd • To Verify > dpd --version • In Workspace, Create REST service name using: • dpd create restusers • This creates a new folder restusers • Change to restusers folder, type dpd • Now, dpd prompt appears • Type, dashboard • Server starts, Home Page for REST service is displayed

  11. Creating Data Structure • In Deployd Dashboard • Click the green button in the Deployd dashboard and type Collection. • Set the name of the collection to /wsusers • Deployd will prompt you to define the properties that the objects in the collection will have. • Add properties required for REST service Data Structure. • After Data Structure Created, • Click Data Link, Add a minimum of 3 records • Click API link, observe URLs for each REST operation

  12. RESTful Service API RESTful Web Service resources and http methods

  13. Angular2 Http Service • The Angular2 Http service facilitates communication with the remote HTTP servers. • Angular 2 uses a pattern called Observables. • The Observable classes in Angular 2 are provided by the ReactiveX library. • The HttpModule from @angular/http library holds providers for a complete set of HTTP services. • We should be able to access these services from anywhere in the application. • So we declare dependency to the AppModule by adding HttpModule to the imports list. @NgModule({ imports: [BrowserModule, HttpModule],

  14. Using Http Service Methods • Use http.get(url) to run our HTTP GET request. • .post(url:string, data:string, requestoptions) • .put(url:string, data:string, requestoptions) • .delete(url:string, requestoptions) • Each Http service method returns an Observable of HTTP Response objects. • An observable is a stream of events that we can process with array-like operators.

  15. Observable Object • An Observable object, which gives us method subscribe() for observing the output. • To receive the output, we call the subscribe() method. • This takes three arguments which are event handlers. • onNext: will receive the HTTP response data. • onError: called if the HTTP request returns an error code • onCompleted: executes after completion of returning all its data • Angular doesn't know that we want to parse the response as JSON.

  16. Consuming REST Api • Use the following with REST web service API • List all Users • Add a New User • Update an Existing User • Delete an Existing User • We use User Service as Data Layer to work with Data operations. • Modify User Class as below: constructor(private id:string, private fname:string, private lname:string){}

  17. List All Users - Service • In AppService, verify is the constructor injects the Http dependency object constructor(private ht:Http){ • Define following member in Service class resturl= “http://localhost:2403/wsusers” • Modify getAllUsers() method getAllUsers(){ return this.ht.get(this.resturl); }

  18. List All Users - Component • Modify the AppComponent Constructor constructor(private asvc:AppService){ this.asvc.getAllUsers().subscribe( (respdata) => console.log("Success ", respdata), (resperr) => console.log("Error", resperr), () => console.log("Completed") ); } • Transforming Response RAW data to JSON format using json(); (respdata) => this.users = respdata.json(),

  19. Add a New User – Form Handling • Define a data member in Component Class newUser:User = new User("", "",""); • Create a Form with Text Boxes to accept User details and bind the text boxes with newUser object members. <form> <input placeholder="Enter First Name" [(ngModel)]="newUser.fname" name="txtFname"> <input placeholder="Enter First Name" [(ngModel)]="newUser.lname" name="txtLname"> <button type="button" (click)="addUser()">Add</button> </form>

  20. Add a New User - Service • Define following members in Service class myheaders = new Headers({'Content-Type': 'application/json'}) options = new RequestOptions({headers:this.myheaders}) • Define addNewUser method addNewUser(newData:User){ return this.ht.post(this.resturl, newData, this.options); }

  21. Adding a New User - Component • Define save() in Component: addUser(){ this.asvc.addNewUser(this.newUser).subscribe( (respdata) => this.users.push(respdata.json()), (err) => console.log("Add Error"), () => console.log("Add Completed") ); this.newUser = new User("","",""); }

  22. Deleting User • In Template, Create a button for each row <button type="button" (click)="deleteUser(u.id)">Delete</button> • In App Service, define a method deleteUser(id:string){ return this.ht.delete(this.restUrl+"/"+id);}

  23. Deleting User - Component • Component Class deleteUser(id:string){ this.asvc.deleteUser(id).subscribe( () => console.log("Delete Success"), () => console.log("Delete Error"), () => console.log("Delete Complete") ); }

  24. Updating UI • Use splice() function to remove an element from an array. • To get the selectedIndex in collection of data, *ngFor provides index property. <tr *ngFor="let u of users; let i = index"> • Pass the index to Component Method from template <button type="button" (click)="deleteUser(u.id, i)">Delete</button> • Modify component method to handle index value deleteUser(id:string, idx:number){ this.asvc.deleteUser(id).subscribe( () => this.users.splice(idx, 1),

  25. Editing User - Template • Create a new Column Heading Action <th>FName</th><th>LName</th><th>Action</th> • Create a Button for each row, <button type="button">Edit</button> • When user clicks the button populate current record data in form elements <td> <button type="button" (click)="editUser(u)">Edit</button> </td> • Define a method in component to populate data in form elements editUser(selectedUser:User) {this.newUser = selectedUser;}

  26. Editing User - Component Copying an Object • The Object.assign() method is used to copy the values of all properties from one or more source objects to a target object. • It will return the target object. • Syntax: Object.assign(target, ...sources) editUser(selectedUser:User) { let cp = Object.assign({}, selectedUser); // Type Cast Object to User this.newUser = <User> cp; }

  27. Updating User - Template • Create an Update button in Form, used to update the changes made by user in Form Elemens. <button type="button" (click)="updateUser()">Update</button> • Add method in service updateUser(user:User){ return this.ht.put(this.resturl, user, this.options); }

  28. Updating User - Component • Define a method in Component Class updateUser(){ this.asvc.updateUser(this.newUser).subscribe( (respdata) => console.log("Update Success"), (err) => console.log("Update Error"), () => console.log("Update Complete.") ); this.newUser = new User("","",""); }

  29. Hands On Exercise • Update the UI after successfully modifying the data source.

  30. Single Page Application • In SPA we load a single HTML page and based on the user request/interaction, we load the other HTML views in the same page, hence the name Single Page Application. • The Web Site is divided into Component Views • The Layout Component is common for all views in our application. • The router is the mechanism for navigating from one component view to another component view. • Router uses a path to navigate to a specific component. • http://localhost:3000/about Now the router navigate us to About Component • Partial Component Views • Partial views are loaded into the layout whenever required. • Partials doesn’t have <html><head><body> Tags.

  31. Creating a Project from Existing Setup • Create a new Project day3project • Create a new Folder src • Create boot.ts file in src folder • Setup the Current Project from existing Project • Install Project Dependencies • Install following additional Angular Modules required for our current project @angular/router • Create Home Page to use web component as below: <myroute-app>Loading. Please Wait... </myroute-app> • Develop <myroute-app> Component and Bootstrap the application and start NPM

  32. Getting Started • Add the base tag in home page at the top of the <head> section. <base href=“/"> • This tag is used to tell the router how to compose navigation URLs. • API required for router is available in RouterModule.

  33. Router Link Directive • Make our AppComponent as our layout component that only handles navigation and loading partials. • The routerLink directive allows us to bind the anchor tag to a string that tells the router where to navigate to the specifed path when the user clicks the link. • Add an anchor tag to the template, when clicked, triggers navigation to the specific Component. selector:"myroute-app", template: `<h2>Route Example</h2> <a routerLink="/">Home |</a> <a routerLink="/about">About |</a> <a routerLink="/contact">Conact |</a> ` })

  34. Router Outlet Directive • Adding a <router-outlet> element to the layout template displays each component that matches to router link. template: `<h2>Route Example</h2> <a routerLink="/">Home |</a> <a routerLink="/about">About |</a> <a routerLink="/contact">Contact |</a> <hr> <router-outlet></router-outlet> `

  35. Creating Partial Components • Create routecomponents.ts import {Component} from "@angular/core"; @Component({ template: "<h3>This is Home Component</h3>" }) export class HomeComponent {} • Create AboutComponent @Component({ template: "<h3>About Component Page</h3>" }) export class AboutComponent {} • Create ContactComponent • Register the components in Application Module

  36. Configuring Routes – Add Routing • Routing is Navigation between different views. • The Angular router is an external, optional Angular Module called RouterModule. • The router is a combination of multiple provided services (RouterModule), multiple directives (RouterOutlet, RouterLink, RouterLinkActive), and a configuration (Routes). • Every time the current route changes, the included view changes with it according to the configuration of your application. • Make the RouterModule available for our Application i.e. our Module is depends on RouterModule • Declare the dependencies in imports array of @NgModule decorator

  37. Hands On Example • In Application Module, Use the forRoot method for configuring routes. • It is a collection of pathnames mapped with components. @NgModule({ imports: [BrowserModule, RouterModule.forRoot([ {path:"", component:HomeComponent}, {path:"about", component:AboutComponent}, {path:"contact", component:ContactComponent} ])], • Run the Application and verify all the Links

  38. Refactoring Route Configuration const myroutes:Routes = [ {path:"", component:HomeComponent}, {path:"about", component:AboutComponent}, {path:"contact", component:ContactComponent} ] @NgModule({ imports: [BrowserModule, RouterModule.forRoot(myroutes)],

  39. Shadow DOM - Unique Component Styles • Templates sometime require unique styles • We can inline the styles directly using styles attributestyles: ["h3 {color: blue}"], template: `<h3>This is Home Component</h3> • We can use external stylesheet styleUrls styleUrls: [‘app/styles/app.component.css’]

  40. Hands On Exercise • Create a NotFoundComponent for any other unmatched routes. • In path use: path : “**”

  41. Pipes • Angular provides you with the pipes mechanismto format or transform the data in the template. • The general syntax for using pipe is: {{ expression | pipeName : inputParam }} • A pipe takes data as input and transforms it to the desired output. • An expression is followed by the pipe symbol |, which is followed by the pipe name and then an optional parameter (inputParam1) separated by a colon (:). • The framework comes with multiple predefined pipes such as date, number, lowercase, uppercase, and others.

  42. Using Pipes • In home Component, Create a property price: number = 100.1234; • Display in template <p>{{ price }}</p>` • A pipe takes data as input and transforms it to a desired output. • Using currency pipe{{ price | currency }} • Pipe with parameter {{price| currency:’INR’ }} • Chaining Pipes: We can chain pipes together to make use of multiple pipes in one expression.{{ price | currency | lowercase }}

  43. Hands On Exercise • Create myDate property and display current system date • {{myDate}} • Transform the Current date into simplified date {{myDate | date}} • Display the date in month / day / year format • {{myDate | date:"MM/dd/yy"}} • Create a product name property and display product name in uppercase. • productname: string = "Sony TV"; {{productname | uppercase}} • Display Product Name in Reverse Format.

  44. Custom Pipes • We need to display product name in reverse format. • Angular2 doesn’t have built-in pipe. • In this situation, need to create user defined pipes called as custom pipes. • Each custom pipe implementation must: • have the @Pipe decorator with pipe metadata that has a name property. • This value will be used to call this pipe in template expressions. • Implement the PipeTransform interface's transform method. • This method takes the value being piped and a variable number of arguments of any type and return a transformed ("piped") value. • We must include our pipe in the declarations array of the AppModule.

  45. Hands On Example • Create a new typescript file app.pipe.ts import {Pipe, PipeTransform} from "@angular/core" @Pipe({name:"reverseText"}) export class ReversePipe implements PipeTransform { transform(value){ return value.split("").reverse().join(""); } } • In App Module declarations: [AppComponent, ReversePipe], • Apply pipe in template. {{productName | uppercase | reverseText}}

  46. Angular2 Project Setup • There are various options to create Angular2 Project Setup: • Manual Setup • Use Quick Start files – Download from angular.io • Angular CLI Tool – Generates boilerplate code.

  47. Angular CLI • One of the easiest ways start a new Angular 2 application is to use the Angular command-line interface (CLI) that allows you to: • generate boilerplate code for new Angular 2 applications • add features (components, directives, services, pipes, etc) to Angular 2 applications • To install Angular CLI: npm install -g @angular/cli • which will install the ng command globally on your system. • To verify whether your installation completed successfully: ng version which should display the version you have installed.

  48. Using Angular CLI • Now that we have Angular CLI installed, we can use it to generate our Todo application: ng new mytestproject • This will create a new directory for us with everything we need to get started • # enter new directory the CLI created for you cd mytestproject • # start the development server ng serve • which will start a local development server that you can navigate to in your browser on http://localhost:4200/. • The application will automatically reload when a source file has changed.

  49. File Name Conventions • Each unit test is put into its own separate file. • The Angular team recommends putting unit test scripts in a .spec filename extension to mark it as a testing script (this is a Jasmine convention). • So if you had a component /app/components/mycomponent.ts, then your unit test for this component would be in /app/components/mycomponent.spec.ts.

  50. Using Angular CLI • Angular CLI can also help us generate necessary code to our existing Angular application using the ng generate command: • # Generate a new component ng generate component my-new-component • # Generate a new pipe ng generate pipe my-new-pipe • # Generate a new service ng generate service my-new-service • # Generate a new class ng generate class my-new-class • # Generate a new interface ng generate interface my-new-interface

More Related