Angular 2 Application with Webpack Denny Angkasa – DG14-0

Contents Setting Up the Project ................................................................................................................................... 3 Angular 2 Dependencies ........................................................................................................................... 3 Typescript Dependencies .......................................................................................................................... 4 Typescript Configuration....................................................................................................................... 5 Webpack Dependencies ........................................................................................................................... 8 Webpack Configuration ........................................................................................................................ 8 Starting to develop Angular 2 Applications ................................................................................................ 11 Creating the Web Page ........................................................................................................................... 11 Best Practice............................................................................................................................................ 12 Bootstrapping the Application ................................................................................................................ 12 Application Module................................................................................................................................. 12 Imports ................................................................................................................................................ 13 Declarations ........................................................................................................................................ 13 Bootstrap ............................................................................................................................................ 13 Application Component .......................................................................................................................... 13 Selector ............................................................................................................................................... 14 Template ............................................................................................................................................. 14 Vendor..................................................................................................................................................... 14 Running the Application.......................................................................................................................... 15 Routing and Multiple Components ......................................................................................................... 17 Building a Simple CRUD Application ........................................................................................................... 20 Setting Up................................................................................................................................................ 20 Listing Products ....................................................................................................................................... 24 Inserting a product .................................................................................................................................. 28 Deleting a Product .................................................................................................................................. 33 Editting a product ................................................................................................................................... 35 Closing ......................................................................................................................................................... 39

Setting Up the Project We are going to set up our project by installing the dependencies and configuring our package.json. Create a folder named angular2-webpack. Open a command window inside it and execute the command: npm init -f

It will generate a package.json file with the content as outputted in the console.

Angular 2 Dependencies Now we are going to install our Angular 2 dependencies. We are going to install those dependencies via the command window with the command: npm install --save @angular/common @angular/compiler @angular/core @angular/platformbrowser @angular/platform-browser-dynamic es6-shim reflect-metadata [email protected] zone.js The command will install the packages separated by space, with --save indicating that the package information should be saved to the package.json file.

Typescript Dependencies Typescript is a superset of Javascript, which means that it is based on Javascript, and everything that works in Javascript should work in typescript, with some restrictions because Typescript requires its code to be strong typed. The strong typing aims to help our code to have fewer mistakes and bugs. Angular 2 officially uses typescript in its documentation and recommends the use of typescript. A linter will mark our code if there are mistakes or if the code violates a standard. We are going to use the Typescript linter tslint. We are going to install the tslint with the command npm install--save-dev typescript tslint typings Notice the parameter --save-dev. It is used to install the dependencies as devDependencies. DevDependencies are dependencies that are used only in development, and not needed in a production environment.

Thus if we open up our package.json, we will see that the typescript dependencies go into devDependencies.

Typescript Configuration We have to configure typescript for our project. First we are going to execute the command: “node_modules/.bin/typings” init This will create typings.json file in our project folder.

Now we are going to install the dependencies with the command: "node_modules/.bin/typings" install dt~es6-shim dt~jasmine env~node --save --global

And then install es6-promise npm install es6-promise It will create a new typings folder, and the typing.json file should look like this

Then we are going to create tsconfig.json file in our project folder and use it to configure our typescript compiler

1. { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. }

"compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false, "suppressImplicitAnyIndexErrors": true }, "exclude": [ "node_modules", "typings/main", "typings/main.d.ts" ]

Webpack Dependencies Webpack is a module bundler. It takes modules with dependencies and emits static assets representing those modules. This means that it can take all of our javascript files and bundle it into only a single javascript file to be used, minimizing the amounts of requests and increasing performance. It also has webpack-dev-server that we can use as a development server for our Angular 2 application. npm install --save-dev webpack webpack-dev-server html-webpack-plugin raw-loader ts-loader

Webpack Configuration After that, we are going to create the file webpack.config.js to configure our webpack 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.

'use strict'; const const const const

debug = process.env.NODE_ENV !== 'production'; HtmlWebpack = require('html-webpack-plugin'); path = require('path'); webpack = require('webpack');

const rootDir = __dirname; module.exports = { debug: true, devtool: debug ? "inline-source-map" : null, entry: { app: [ path.resolve(rootDir, 'src', 'js', 'client') ], vendor: [ path.resolve(rootDir, 'src', 'js', 'vendor') ] }, module: { loaders: [

23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. };

{ test: /\.(css|html)$/, loader: 'raw' }, { test: /\.ts$/, exclude: /node_modules/, loaders: ['ts'] } ] }, output: { path: path.resolve(rootDir, 'dist'), filename: '[name].bundle.js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ filename: 'vendor.bundle.js', minChunks: Infinity, name: 'vendor' }), new HtmlWebpack({ filename: 'index.html', inject: 'body', template: path.resolve(rootDir, 'src', 'index.html') }) ], devServer: { contentBase: path.resolve(rootDir, 'dist'), port: 8080 }, resolve: { extensions: ['', '.js', '.ts'] }

Use Strict Use strict will enable strict mode in javascript, which for example will prevent the use of undeclared variable. Devtool Devtool inline-source-map will map the bundle to our original javascript file so we can easily debug our source code using the browser’s inspector as it will behave as if we are debugging our original files. Entry Entry defines the entry point for the bundler into our application. It will bundle all dependencies starting from the entry point. We are going to use two entry points, app and vendor. App will only contain the source code of our application, and vendor will contain all the third party modules. Module Loaders We are going to use raw loader for css and html, and use ts loader for typescript. We are going to output the result in our projectfolder/dist.

Plugins We are going to use plugins for the development. CommonsChunkPlugin will make our app bundle clean if it is contained inside the vendor bundle. HtmlWebpackPlugin will simplify our html. DevServer option is used to configure our webpack-dev-server which we will be using in the development of this application.

Starting to develop Angular 2 Applications We are going to put all of our source codes inside src folder. Our project directory should look like this

Creating the Web Page Create the file index.html inside src folder. 1. 2. 3. 4. 5. Angular 2 App 6. 7. 8. 9. Loading... 10. 11.

This index.html will be the main page of our application, since we are creating a single page application. Inside the src folder create a new folder called js.

Best Practice In developing our Angular 2 Application, we are going to ensure that one file contains only one modular component of our application. For example: a module file will only contain one module, a component file will only contain one component, etc.

Bootstrapping the Application We are going to create the entry point to our application, which we specified in our webpack.config.js. We are going to bo otstrap our application with @angular/platform-browser-dynamic module. Create the file client.ts inside js folder 1. import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2. 3. import { AppModule } from './app.module'; 4. 5. platformBrowserDynamic().bootstrapModule(AppModule);

Application Module Angular 2 application consists of modules, so we are going to create the main module of our application, the AppModule. This module will act as the root module for our application. Create the file app.module.ts in the same directory as client.ts. 1. import { NgModule } from '@angular/core'; 2. import { BrowserModule } from '@angular/platform-browser'; 3. 4. import { AppComponent } from './app.component';

5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

import { AppRoutes } from './app.routes'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

Imports We import NgModule from @angular/core and use it to create our module. Our main module needs to import BrowserModule for the application to work. The imports property will also be used to import other modules and routing later in our application.

Declarations If we are going to use a component in a view as HTML tag, such as this part in our index.html 1. 2. Loading... 3.

Notice that the tag is from the Angular 2 Application. Then the component that the module uses needs to be declared in the declarations property. If it is already declared in the child module, then the parent module only need to import the child module.

Bootstrap The root module needs to declare a component to be bootstrapped. Here it is going to be our AppComponent.

Application Component Notice that we are importing AppComponent in our ApplicationModule, which we haven’t created yet. Let’s create our AppComponent. A component will serve as the component of our application, which will handle the data, logic, and view of our application. These tasks can be broken down into multiple components to increase decoupling. For now we are only going to create the basic AppComponent. Create the file app.component.ts in the same directory as app.module.ts. 1. import { Component } from '@angular/core'; 2. 3. @Component({

4. selector: 'app', 5. template: require('./app.component.html') 6. }) 7. export class AppComponent { 8. 9. }

Selector The selector property is used as the name of the tag if we are going to use this component in a view. In our index.html we created an tag, so we are going to declare our selector as ‘app’.

Template The template of the component is the view of the component. There are two ways to declare it which are through template or templateUrl property. Since we are using webpack, we can use require to import the html inline into our component. It is the equivalent of this 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

import { Component } from '@angular/core'; @Component({ selector: 'app', template: `

Hello World

` }) export class AppComponent { }

Usually multiline strings are not supported in javascript. Since we are using typescript, we can utilize this feature by using an Acute Accent symbol below the escape key (`). This is the same as requiring an html file containing this 1.

Hello World



Vendor As explained earlier, we are going to use a vendor file to make our application bundle contain only the application code. All third party imports will go in the vendor bundle. Create the file vendor.ts in the same directory as app.component.ts. 1. 2. 3. 4. 5.

import import import import import

'@angular/platform-browser'; '@angular/platform-browser-dynamic'; '@angular/core'; 'zone.js'; 'reflect-metadata';

Running the Application We are going to utilize webpack-dev-server to server static files for our application in development. We have already configured the content base and port in our webpack.config.js. 1. devServer: { 2. contentBase: path.resolve(rootDir, 'dist'), 3. port: 8080 4. }

Now we are going to create a script in package.json to simplify the process of running the application. 1. "scripts": { 2. "test": "echo \"Error: no test specified\" && exit 1", 3. "start": "webpack-dev-server --inline" 4. }

The --inline allows our web page to refresh itself every time there are changes to the bundle. Now we are going to run the application by using running this command in the project root folder. Navigate the command prompt to project root folder and execute npm start

Now go to your web browser and type in the address http://localhost:8080

Congratulations! We have successfully created an Angular 2 application using webpack and serve it with webpack-dev-server. If we look at the network tab, we can see that it automatically loads app.bundle.js and vendor.bundle.js into our application. Now let’s check our dist folder. If we try to change our

app.component.html file, our webpack-dev-server will automatically rebundle our application and refresh our page.

Here we can see that app.bundle.js which contains only our application code is only 11 Kilobytes in size. The vendor.bundle.js which contains all of our imports is almost 2MB in size. It is because we imported all of our module in vendor.ts. Our CommonsChunkPlugin will take out those third party code that we imported in our vendor.ts from our app bundle. By configuring our application like this, it will be much easier to maintain in the future.

Routing and Multiple Components We are going to implement routing with multiple components in our application. A single page application routing works differently compared to web server routings such as PHP, ASP.NET, or Node.Js. When we route our single page application, it will change the URL without actually refreshing the page, instead changing a part of the page. We write the part that changes according to routing as in Angular 2. Our application component will be the main component of our application that contains the router outlet. Change our app.component.html to this 1. 2. 3. 4.

My Application

Home About

We now have “My Application” as the header and 2 router links linking to home and about page. Now we are going to define our routing. Create a new file app.routes.ts in the same folder as app.component.html. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.

import { ModuleWithProviders } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; export const AppRoutes: ModuleWithProviders = RouterModule.forRoot(routes);

The routing means that our “/” path will redirect to “home”, so we essentially have only “home” and “about” route each with its own components. Now that we have our routing, we have to import this routing to our Application Module. Change our app.module.ts to this 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { AppRoutes } from './app.routes'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; @NgModule({ imports: [ BrowserModule, RouterModule, AppRoutes ], declarations: [ AppComponent, HomeComponent, AboutComponent ], bootstrap: [ AppComponent ] })

26. export class AppModule { 27. 28. }

For now, we are declaring all of our components inside our Application Module. Now we are going to create our components using the path that we used to import the components. Create the folder home and create home.component.ts. 1. 2. 3. 4. 5. 6. 7. 8.

import { Component } from '@angular/core'; @Component({ template: 'THIS IS HOME' }) export class HomeComponent { }

Create the folder about and create about.component.ts. 1. 2. 3. 4. 5. 6. 7. 8.

import { Component } from '@angular/core'; @Component({ template: 'THIS IS ABOUT' }) export class AboutComponent { }

Now go to the browser and our single page application with routing should be working perfectly, with the default page being Home because of the redirect from ‘/’.

Building a Simple CRUD Application Now we are going to use what we have learned to create a simple CRUD application about products. We are going to use the skeleton of our previous project and improve it to create our new application.

Setting Up Change our package.json to this 1. { 2. "name": "angular2-webpack", 3. "version": "1.0.0", 4. "description": "", 5. "main": "index.js", 6. "scripts": { 7. "test": "echo \"Error: no test specified\" && exit 1", 8. "start": "webpack-dev-server --inline" 9. }, 10. "keywords": [], 11. "author": "", 12. "license": "ISC", 13. "dependencies": { 14. "@angular/common": "^2.2.4", 15. "@angular/compiler": "^2.2.4", 16. "@angular/core": "^2.2.4", 17. "@angular/forms": "^2.2.4", 18. "@angular/http": "^2.2.4", 19. "@angular/platform-browser": "^2.2.4", 20. "@angular/platform-browser-dynamic": "^2.2.4", 21. "es6-promise": "^4.0.5", 22. "es6-shim": "^0.35.2",

23. "reflect-metadata": "^0.1.8", 24. "rxjs": "^5.0.0-rc.4", 25. "zone.js": "^0.7.2" 26. }, 27. "devDependencies": { 28. "html-webpack-plugin": "^2.24.1", 29. "raw-loader": "^0.5.1", 30. "ts-loader": "^1.3.0", 31. "typescript": "^2.0.10", 32. "typings": "^2.0.0", 33. "webpack": "^1.13.3", 34. "webpack-dev-server": "^1.16.2" 35. } 36. }

Run this command in the project folder npm install For refreshment, here are the files that we are going to have now relative to our project folder ./webpack.config.js 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.

'use strict'; const const const const

debug = process.env.NODE_ENV !== 'production'; HtmlWebpack = require('html-webpack-plugin'); path = require('path'); webpack = require('webpack');

const rootDir = __dirname; module.exports = { devtool: debug ? "inline-source-map" : null, entry: { app: [ path.resolve(rootDir, 'src', 'js', 'client') ], vendor: [ path.resolve(rootDir, 'src', 'js', 'vendor') ] }, module: { loaders: [ { test: /\.(css|html)$/, loader: 'raw' }, { test: /\.ts$/, exclude: /node_modules/, loaders: ['ts'] } ] }, output: {

34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. };

path: path.resolve(rootDir, 'dist'), filename: '[name].bundle.js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ filename: 'vendor.bundle.js', minChunks: Infinity, name: 'vendor' }), new HtmlWebpack({ filename: 'index.html', inject: 'body', template: path.resolve(rootDir, 'src', 'index.html') }) ], devServer: { contentBase: path.resolve(rootDir, 'dist'), port: 8080 }, resolve: { extensions: ['', '.js', '.ts'] }

./src/js/app.component.ts 1. 2. 3. 4. 5. 6. 7. 8. 9.

import { Component } from '@angular/core'; @Component({ selector: 'app', template: require('./app.component.html') }) export class AppComponent { }

./src/js/app.module.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule, CommonModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] })

19. export class AppModule { 20. 21. }

./src/js/app.component.html 1.
2. Hello World 3.


./src/index.html 1. 2. 3. 4. 5. Angular 2 App 6. 7. 8. 9. 10. Loading... 11. 12.

We are also going to use bootstrap to prettify our application. You can download it from https://bootswatch.com/bower_components/bootstrap/dist/css/bootstrap.min.css The file structure should be like this

Now we should have a nice page with the text “Hello World”

Listing Products Now we are ready to create our application. Let’s create our page header and the list for our products ./src/js/app.component.ts

1.
2. 3.
4.
5. Product Id 6.
7.
8. Product Name 9.
10.
11. Quantity 12.
13.
14. 15. 16.


Notice we are going to use components to break down our page into small modules. A component in our application will serve only its purpose, in this case showing a list of product. Since we are going to divide our application into small components, we have to store our data in our higher level component, in this case our ApplicationComponent.

That line means we are going to repeat our product-component according to our products data with *ngFor="let product of products", and pass a product into product-component with [product]="product". Let’s create the data as dummy data for now in our ApplicationComponent, and other methods to modify our data later on. We are going to call the dev method in our constructor to fill our products with dummy data for now. ./src/js/application.component.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.

import { Component } from '@angular/core'; import { Product } from './models/product.model'; @Component({ selector: 'app', template: require('./app.component.html') }) export class AppComponent { products: Array = []; idCounter: number = 1; constructor() { this.dev(); } dev() { this.products.push(new Product(1, 'Product 1', 45)); this.products.push(new Product(2, 'Product 2', 12)); this.idCounter = 3; }

23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. }

addNewProduct(product: Product) { product.id = this.idCounter++; this.products.push(product); } deleteProduct(id: number) { for(var i = 0; i
Now we are going to use model in our application to ensure data integrity. Let’s create our product model ./src/js/models/product.model.ts 1. export class Product { 2. 3. public id: number; 4. public name: string; 5. public quantity: number; 6. 7. constructor(id, name, quantity) { 8. this.id = id; 9. this.name = name; 10. this.quantity = quantity; 11. } 12. }

Now let’s create the actual component that is going to render our datas. ./src/js/product/product.component.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.

import { Component, Input } from '@angular/core'; import { Product } from '../models/product.model'; @Component({ selector: 'product-component', template: require('./product.component.html'), styles: [ require('./style.css') ] }) export class ProductComponent { @Input() product: Product; constructor() { }

18. }

Input is used to accept inputs from parent component, which is the product that we passed from ApplicationComponent earlier. ./src/js/product/product.component.html 1.
2.
3. {{ product.id }} 4.
5.
6. {{ product.name }} 7.
8.
9. {{ product.quantity }} 10.
11.
12. 13. 14. 15.
16.


Now let’s create a style.css for product component to prettify our application 1. 2. 3. 4. 5. 6. 7. 8.

.product-row { height: 50px; line-height: 50px; } .prod-button { width: 70px; }

Now update our application module because every component that we use needs to be declared in a module ./src/js/app.module.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { AppComponent } from './app.component'; import { ProductComponent } from './product/product.component'; @NgModule({ imports: [ BrowserModule,

11. CommonModule 12. ], 13. declarations: [ 14. AppComponent, 15. ProductComponent 16. ], 17. bootstrap: [ 18. AppComponent 19. ] 20. }) 21. export class AppModule { 22. 23. }

Now we can go to our application and see that our products should appear nicely

Inserting a product Now since we are going to divide our application into components, we are going to create a new component to handle data insertion for us. Let’s create our component to insert products. Update application module ./src/js/app.module.ts 1. 2. 3. 4. 5. 6. 7.

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { AppComponent } from './app.component'; import { ProductComponent } from './product/product.component'; import { InsertProductComponent } from './product/insert-product.component';

8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.

@NgModule({ imports: [ BrowserModule, CommonModule ], declarations: [ AppComponent, ProductComponent, InsertProductComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

./src/js/product/insert-product.component.ts 1.

Insert New Product

2.
3.
4. 5. 6.
7.
8. 9. 10.
11.
12. 13.
14.
15. {{ errorMessage }} 16.
17.


./src/js/product/insert-product.component.html 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

import { Component, Output, EventEmitter } from '@angular/core'; import { Product } from '../models/product.model'; @Component({ template: require('./insert-product.component.html'), selector: 'insert-product-component' }) export class InsertProductComponent { private productName: string; private quantity: number; private errorMessage: string;

14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. }

@Output() addProduct = new EventEmitter(); onSubmit() { var newProduct = new Product(null, this.productName, this.quantity); if(!this.validate()) return; this.addProduct.emit(newProduct); this.clearForm(); } validate() { if(this.productName == null || this.productName == '') this.errorMessage = 'Fill in the product name'; else if(this.quantity == null) this.errorMessage = 'Fill in the quantity'; else this.errorMessage = null; return this.errorMessage == null; } clearForm() { this.productName = null; this.quantity = null; this.errorMessage = null; }

Output and EventEmitter are used to emit data from child component to parent component. We need this to signal our parent component when inserting a new product because the data is stored in ApplicationComponent. ./src/js/product/insert-product.component.html 1.

Insert New Product

2.
3.
4. 5. 6.
7.
8. 9. 10.
11.
12. 13.
14.
15. {{ errorMessage }} 16.
17.


Notice we are using ngForm in our application to make our ngSubmit method works. This requires our module to import FormsModule. ./src/js/app.module.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.

import import import import

{ { { {

NgModule } from '@angular/core'; BrowserModule } from '@angular/platform-browser'; CommonModule } from '@angular/common'; FormsModule } from '@angular/forms';

import { AppComponent } from './app.component'; import { ProductComponent } from './product/product.component'; import { InsertProductComponent } from './product/insert-product.component'; @NgModule({ imports: [ BrowserModule, CommonModule, FormsModule ], declarations: [ AppComponent, ProductComponent, InsertProductComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

Now the last thing to do is to include the component in our view ./src/js/app.component.html 1.
2. 3. 4. 5.
6.
7. Product Id 8.
9.
10. Product Name 11.
12.
13. Quantity 14.
15.
16. 17. 18.


(addProduct)="addNewProduct($event)" means that when addProduct is emitted, we are going to

execute addNewProduct in our application component. We should now be able to insert data into our application

Deleting a Product We have previously created a delete method in our application component. To make that work, we just have to inject it to our delete button. We are going to use the same method as insert component used, which is to use output and eventemitter to signal our application component to delete a certain data. ./src/js/product/product.component.html 1.
2.
3. {{ product.id }} 4.
5.
6. {{ product.name }} 7.
8.
9. {{ product.quantity }} 10.
11.
12. 13. 14. 15.
16.


./src/js/product/product.component.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.

import { Component, Input, Output, EventEmitter } from '@angular/core'; import { Product } from '../models/product.model'; @Component({ selector: 'product-component', template: require('./product.component.html'), styles: [ require('./style.css') ] }) export class ProductComponent { @Input() product: Product; @Output() productDeleted = new EventEmitter(); constructor() { } deleteProduct() { this.productDeleted.emit(this.product.id); } }

Now let’s receive the event in our ApplicationComponent

./src/js/app.component.html 1.
2. 3. 4. 5.
6.
7. Product Id 8.
9.
10. Product Name 11.
12.
13. Quantity 14.
15.
16. 17. 18.


We should now be able to delete our product by clicking on the delete button

Editting a product Now we are going to implement the functionality of editting a product. Let’s divide this into another component, where it is going to be the child of ProductComponent. ./src/js/product/edit-product.component.html 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

Name
Quantity


./src/js/product/edit-product.component.ts 1. import { Component, Input, Output, EventEmitter } from '@angular/core'; 2. 3. import { Product } from '../models/product.model'; 4. 5. @Component({ 6. template: require('./edit-product.component.html'), 7. selector: 'edit-product'

8. }) 9. export class EditProductComponent { 10. 11. @Input() product: Product; 12. }

The code to do this is not that long because we are utilizeng 2 way data binding to change our data, so we can directly change the data directly through the input provided in the application. The product data will be an input from our ProductComponent, and it will change the data all the way to the data in ApplicationComponent because they are essentially the same data. Now let’s implement this into our ProductComponent ./src/js/product/product.component.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.

import { Component, Input, Output, EventEmitter } from '@angular/core'; import { Product } from '../models/product.model'; @Component({ selector: 'product-component', template: require('./product.component.html'), styles: [ require('./style.css') ] }) export class ProductComponent { private edittingProduct: boolean; @Input() product: Product; @Output() productDeleted = new EventEmitter(); constructor() { } deleteProduct() { this.productDeleted.emit(this.product.id); } editProduct() { this.edittingProduct = true; } cancelEditProduct() { this.edittingProduct = false; } }

./src/js/product/product.component.html 1.
2.
3. {{ product.id }} 4.
5.


6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.

{{ product.name }}
{{ product.quantity }}


Now the last but not least, don’t forget to declare our new component in the ApplicationModule ./src/js/app.module.ts 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.

import import import import

{ { { {

NgModule } from '@angular/core'; BrowserModule } from '@angular/platform-browser'; CommonModule } from '@angular/common'; FormsModule } from '@angular/forms';

import import import import

{ { { {

AppComponent } from './app.component'; ProductComponent } from './product/product.component'; InsertProductComponent } from './product/insert-product.component'; EditProductComponent } from './product/edit-product.component';

@NgModule({ imports: [ BrowserModule, CommonModule, FormsModule ], declarations: [ AppComponent, ProductComponent, InsertProductComponent, EditProductComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

Now we should be able to edit our data by clicking on the Edit button

Closing Congratulations! You can now build applications using Angular 2 Javascript framework. Angular 2 is very useful for single page application development because of its powerful and easy to use features, such as data binding, modules, component compiling, and much more. Developing a large single application without a framework can be messy and tedious because the codes tend to pile up and become very complex. By using Angular 2 and its powerful features, dividing our application into multiple component and modules, we can manage and scale our application easily. Take our newly created application for example. In our application, we never have to touch the Application Component ever again after creating it, because we are developing our features, which is product CRUD in a new component inside Application Component. This means when we have to make changes to parts of our application, we only have to deal with the associated components and modules, instead of checking the whole application for the responsible piece of code.

References https://udemy-images.udemy.com/course/750x422/756150_c033.jpg

Angular 2 Application with Webpack

app.component.html file, our webpack-dev-server will automatically rebundle our application and refresh our page. Here we can see that app.bundle.js which contains only our application code is only 11 Kilobytes in size. The vendor.bundle.js which contains all of our imports is almost 2MB in size. It is because we imported.

2MB Sizes 0 Downloads 118 Views

Recommend Documents

Download ANGULAR 2 DEVELOPMENT WITH ...
About the Author Yakov Fain has been a developer for more than 25 years and has written multiple books on software development.Anton Moiseev has 8 years ...

How webpack works - GitHub
M. Sc. Computer Science. • Started with Open Source in 2012 as Hobby. • Since 2017: Freelancer (Open Source + Consulting). • Father of a 2-months old ...

Download [PDF] Angular 2 Development with ...
PDF )一覧React is a popular JavaScript technology for creating rich user ... app store ready hybrid apps with the Ionic 2 the framework built on top of Apache .... web clients or fullfeatured SPAs, using the Angular 2 web framework is

ePub Download Angular 2 Development with ...
Angular 2 Development with TypeScript free pdf Download, Angular 2 .... Angular 2 applications to Angular 2 Web Development with TypeScript Download this book ... Its declarative style makes it easy to define and add features without a lot of ...

[PDF Download] Angular 2 Development with ...
Pdf Angular 2 Development with TypeScript online download, Read epub Angular 2 Development with TypeScript, .... experienced web application developers.