app.component.html file, our webpack-dev-server will automatically rebundle our application and refresh our page. Here w
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-meta> 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 >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-meta> 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. Simple CRUD Application 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 [product]="product">
That line means we are going to repeat our product-component according to our products , and pass a product into product-component with [product]="product". Let’s create the > 2. 3. {{ product.id }} 4. 5. 6. {{ product.name }} 7. 8. 9. {{ product.quantity }} 10. 11. 12. Edit 13. Close 14. Delete 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 #f="ngForm"> 3. 4. Name 5. 6. 7. 8. Quantity 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 #f="ngForm"> 3. 4. Name 5. 6. 7. 8. Quantity 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. Simple CRUD Application 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 > 2. 3. {{ product.id }} 4. 5. 6. {{ product.name }} 7. 8. 9. {{ product.quantity }} 10. 11. 12. Edit 13. Close 14. Delete 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. Simple CRUD Application 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 > 2. 3. {{ product.id }} 4. 5.
6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
{{ product.name }} {{ product.quantity }} Edit Close Delete
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