- Home
- >
- Mobile apps development
- >
- Get started with Angular 5 Tutorial
Let’s get started with your Angular 5 tutorial. First, let me introduce you to Angular 5. Angular 5 is a new version of the AngularJS framework. It is developed by Google. It comes with various improvements like optimized build and faster compile times. Angular 5 also comes with a complete rewrite.
If you want to learn Angular 5 this Angular 5 tutorial is for you. Here we are going to build a notes app from scratch.
There are two versions of frameworks:-
-AngularJS(Version 1)
-Angular(Version 2+)
There is a huge difference between these two is AngularJS is a javascript framework but version 2 Angular is not a javascript framework.
Conflict b/w use or not to use Angular 5:-
Some developers prefer to use React and build their components without additional codes. But that may be a problem, too.
On the other hand, some developers choose Angular as it is a fully integrated framework. Angular allows you to quickly start working on your project without giving thought about which library to select and also how to deal with everyday problems. That is why here we are building our first Angular 5 App.
TypeScript
TypeScript is easy to learn if you have a good knowledge of JavaScript. Most modern editors are quite effective in helping with that. Nowadays the most preferable options are VSCode and any of the JetBrains IntelliJ family-like Webstorm and RubyMine.
It’s good to use a smarter editor than vim. As TypeScript is strongly typed, it will give you an extra hands-up on any mistakes in the code. One more thing is that Angular CLI with its Webpack takes care of compiling TypeScript to JavaScript. So you shouldn’t let the IDE compile it for you.
Angular CLI
Angular has its own CLI (command line interface), which will do most of the routines for you. You have to install it first to start using Angular. It requires Node 6.9.0 or higher as well as NPM 3 or Higher. You need to install both for that find up-to-date documentation for installation. Once they both install, you can install Angular CLI by running the following.
npm install -g @angular/cli
Once you successfully install Angular CLI, you can generate a new project by running the ng new command.
ng new getting-started-ng5
create getting-started-ng5/README.md (1033 bytes)
create getting-started-ng5/.angular-cli.json (1254 bytes)
create getting-started-ng5/.editorconfig (245 bytes)
create getting-started-ng5/.gitignore (516 bytes)
create getting-started-ng5/src/assets/.gitkeep (0 bytes)
create getting-started-ng5/src/environments/environment.prod.ts (51 bytes)
create getting-started-ng5/src/environments/environment.ts (387 bytes)
create getting-started-ng5/src/favicon.ico (5430 bytes)
create getting-started-ng5/src/index.html (304 bytes)
create getting-started-ng5/src/main.ts (370 bytes)
create getting-started-ng5/src/polyfills.ts (2405 bytes)
create getting-started-ng5/src/styles.css (80 bytes)
create getting-started-ng5/src/test.ts (1085 bytes)
create getting-started-ng5/src/tsconfig.app.json (211 bytes)
create getting-started-ng5/src/tsconfig.spec.json (304 bytes)
create getting-started-ng5/src/typings.d.ts (104 bytes)
create getting-started-ng5/e2e/app.e2e-spec.ts (301 bytes)
create getting-started-ng5/e2e/app.po.ts (208 bytes)
create getting-started-ng5/e2e/tsconfig.e2e.json (235 bytes)
create getting-started-ng5/karma.conf.js (923 bytes)
create getting-started-ng5/package.json (1324 bytes)
create getting-started-ng5/protractor.conf.js (722 bytes)
create getting-started-ng5/tsconfig.json (363 bytes)
create getting-started-ng5/tslint.json (3040 bytes)
create getting-started-ng5/src/app/app.module.ts (316 bytes)
create getting-started-ng5/src/app/app.component.css (0 bytes)
create getting-started-ng5/src/app/app.component.html (1141 bytes)
create getting-started-ng5/src/app/app.component.spec.ts (986 bytes)
create getting-started-ng5/src/app/app.component.ts (207 bytes)
Installing packages for tooling via yarn.
yarn install v1.3.2
info No lockfile found.
[1/4] ? Resolving packages...
[2/4] ? Fetching packages...
[3/4] ? Linking dependencies...
warning "@angular/cli > @schematics/[email protected]" has incorrect peer dependency "@angular-devkit/[email protected]".
warning "@angular/cli > @angular-devkit/schematics > @schematics/[email protected]" has incorrect peer dependency "@angular-devkit/[email protected]".
[4/4] ? Building fresh packages...
success Saved lockfile.
✨ Done in 44.12s.
Installed packages for tooling via yarn.
Successfully initialized git.
Project 'getting-started-ng5' successfully created.
When it’s done, you can ask for your fresh application to start by running ng serve out of its directory:
ng serve
** NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
Date: 2017-12-13T17:48:30.322Z
Hash: d147075480d038711dea
Time: 7425ms
chunk {inline} inline.bundle.js (inline) 5.79 kB [entry] [rendered]
chunk {main} main.bundle.js (main) 20.8 kB [initial] [rendered]
chunk {polyfills} polyfills.bundle.js (polyfills) 554 kB [initial] [rendered]
chunk {styles} styles.bundle.js (styles) 34.1 kB [initial] [rendered]
chunk {vendor} vendor.bundle.js (vendor) 7.14 MB [initial] [rendered]
webpack: Compiled successfully.
When you navigate your browser to that link, It will be displayed as pictured here:
Let’s get started with Angular 5 Tutorial
Now let’s see what is actually happening here. Angular CLI runs webpack dev server, which renders your app on the next free port because of this you can run multiple apps on the same machine with live reload. It also watches for every change in the project source and recompiles all changes. After that, it asks the browser to reload the open page. So we are already working in a development environment without writing a line of configuration by using Angular CLI. But it’s just a start here…
App composition in angular
You have your empty app running. Now let’s talk about app composition in Angular. If you have basic knowledge of AngularJS you know there were controllers, directives, and components that were somehow like directives but simpler, to allow you to upgrade to Angular 2.
Those who don’t have that wonderful experience of having to choose between them and also figure out what goes where. But you do not need to worry. Nowadays it’s mostly just a component. In the Angular world component is the most basic building block.
Let’s look at the code that was generated for you by Angular CLI.
First, here’s index.html :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GettingStartedNg5</title>
<base href="https://codersera.com/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="https://codersera.com/blog/an-angular-5-tutorial-step-by-step-guide-to-your-first-angular-5-app/favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
It looks like the kind of markup. But there’s a special tag, app-root. How does Angular make this work, and how can we know what’s happening inside it?
Let’s open the src/app directory and see what’s there. You can see ng new output from earlier here or open it in your chosen IDE. You will see app.component.ts there were the next bit( this may vary depending on how recent your version of Angular is):
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title="app";
}
@components(—) here looks like a function call. What is it? there is a TypeScript decorator we will discuss it later. For now let’s concentrate on what it’s doing, with passed parameters like selector being used to generate your component declaration. It just goes a lot of boilerplate work for you as well as giving back your component declaration in its working form. You don’t have to implement additional code to support any of the decorator’s params. It’s all handled by the decorator. Generally, it is called the Factory method.
You already saw app-root in your index.html. Here’s how Angular knows how to find the component corresponding to your tag. Obviously, templateUrl and styleUrls define where Angular should take your markup and CSS from. there are a lot more params for the component decorator. We are also going to use some of them in our new app.
Let’s look at the component’s markup:
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>
So, aside from embedding the Angular Logo as an SVG, which is pretty neat, this seems like typical everyday markup as well. Aside from one thing ( Welcome to {{ title }} !), If you look at your component code again, you will see title=’app’;. So, if you already have some practice in template languages or have worked with AngularJS, it’s pretty obvious what’s happening here. It is called Angular Interpolation by which the expression inside the double curly braces is being pulled from your component( you can think of {{ title }} as a simplified form of {{ this.title }} ) and also displayed on your markup.
Now you have seen all the parts of your auto-generated Angular app that actually take place in the page displayed in your browser. Let’s recap how it actually works- Angular CLI runs Webpack, which is compiling your Angular app into Javascripts bundles and injecting them into your index.html. If you take a look at the actual code in your browser using the inspect feature, you see something like this:
Every time you change your code, Angular CLI will recompile, re-inject if needed, and also ask your browser to reload the page if it’s open. Angular does it quite quickly, so in most cases, while you are switching your windows from the IDE to the browser, it will all be reloaded for you.
So let’s start moving towards your goal and, for a start, let’s switch your project from CSS to Sass and open your .angular-cli.json and edit styles and styleExt properties thusly.
"styles": [
"styles.scss"
],
[...]
"defaults": {
"styleExt": "scss",
"component": {}
}
You also need to add Sass library to our project and rename styles.css to styles.scss. So to add Sass you need to use yarn :
yarn add sass
yarn add v1.3.2
[1/4] ? Resolving packages...
[2/4] ? Fetching packages...
[3/4] ? Linking dependencies...
[...]
[4/4] ? Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
└─ [email protected]
✨ Done in 12.06s.
yarn add [email protected] --dev
✨ Done in 5.78s.
If you also want to use Twitter Bootstrap on your project so you also need to runyarn add [email protected] and edit your styles.scss to include this:
/* You can add global styles to this file, and also import other style files */@import "../node_modules/bootstrap/scss/bootstrap";
body {
padding-top: 5rem;
}
you need to edit index.html to make your page responsive by changing the meta for your markup to this:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
And now you can replace app.componant.html with this:
<!-- Fixed navbar -->
<nav>
<a href="#">Angular Notes</a>
</nav>
<div>
<div style="text-align:center">
<h1>
Welcome to {{title}}!
</h1>
</div>
</div>
now, if you open your browser, you see the following:
And that’s it for the boilerplate. Let’s move on to creating your own components.
First Components
Let’s start by generating your first component, representing the card itself. For that, use Angular CLI by running the following command:
ng generate component Card
create src/app/card/card.component.scss (0 bytes)
create src/app/card/card.component.html (23 bytes)
create src/app/card/card.component.spec.ts (614 bytes)
create src/app/card/card.component.ts (262 bytes)
update src/app/app.module.ts (390 bytes)
But if you look into src/app/card/card.component.ts , you can see they are almost the same code, as you have in your AppComponent, with one small difference:
[...]
@Component({
selector: 'app-card',
[...]
export class CardComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
At this point, that it’s considered good practice to preface your component selectors with a common prefix, and by default, it’s app- You can change it to the prefix of your preference by editing the prefix property in .angular-cli.json ,so it’s preferable to do so before using ng generate for the first time.
So, you have a constructor for your component as well as a ngOnInit function for it. On a basic level, think about these methods like this: A constructor is being called right after the creation of the component, long before data to be passed to it is ready and populated, while ngOnInit only runs after the first cycle of changes to the data, so you have access to your component inputs. Just remember that it is preferable to use the constructor for constants, like things that are actually being hard-coded into your component, as well as ngOnInit for everything that depends on external data.
Let’s populate your CardComponent implementation. To start with, let’s just add some markup to it. Default contents for markup are something like this:
<p>
card works!
</p>
Replace it with code so it will behave like a card:
<div>
<div>
<p>Text</p>
</div>
</div>
Now is a good time to display the card component, but this raises additional questions: Who will be responsible for displaying the cards? AppComponent? But AppComponent will be loaded before anything else in the app, so you have to consider it to be tidy and small. you’d better create one more component to take care of storing a list of cards and displaying it on your page.
As described component’s responsibilities, it is clear that this is supposed to be a Card List Component. Let’s ask Angular CLI to generate it for you:
ng generate component CardList
create src/app/card-list/card-list.component.scss (0 bytes)
create src/app/card-list/card-list.component.html (28 bytes)
create src/app/card-list/card-list.component.spec.ts (643 bytes)
create src/app/card-list/card-list.component.ts (281 bytes)
update src/app/app.module.ts (483 bytes)
Before we start implementing it, Angular CLI tells you that it updated app.module.ts for you, correct it:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { CardComponent } from './card/card.component';
import { CardListComponent } from './card-list/card-list.component';
@NgModule({
declarations: [
AppComponent,
CardComponent,
CardListComponent,
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Obviously, BrowserModule and NgModule are internal Angular modules. AppComponent was here before you started to generate any code, so your new components actually populated the modules in two places. First, they are imported from their definition files and then they are included in the declaration array of your NgModule Decorator. If you are creating a new component from scratch and forget to add a new module to NgModule but try to add it to your markup, your app won’t work with the next error in the JS console.
Uncaught Error: Template parse errors:
'app-card-list' is not a known element:
1. If 'app-card-list' is an Angular component, then verify that it is part of this module.
2. If 'app-card-list' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
So check your console if your app is not working for no apparent reason.
Let’s populate your card list component markup ( src/app/card-list/card-list.component.html )
<div>
<div>
<app-card></app-card>
<app-card></app-card>
<app-card></app-card>
</div>
</div>
If you open it in your browser, you will see something like this :
Currently displaying cards out of the hard-coded markup. Let’s bring your code one step closer to a real case scenario by moving a hard-coded array of cards into your application:
export class AppComponent {
public cards: Array<any> = [
{text: 'Card 1'},
{text: 'Card 2'},
{text: 'Card 3'},
{text: 'Card 4'},
{text: 'Card 5'},
{text: 'Card 6'},
{text: 'Card 7'},
{text: 'Card 8'},
{text: 'Card 9'},
{text: 'Card 10'},
];
}
You have your initial list, but still, you need to pass it to the component and render it there. for that, you need to create your first input. Let’s add it to your CardList component:
import {Component, Input, OnInit} from '@angular/core';
[...]
export class CardListComponent implements OnInit {
@Input() cards: Array<any>;
[...]
Imported Input from the Angular code and used it as a decorator for class-level variables cards with type Array of objects of any kind. Ideally, you should not use any but should use strict typing so that you can define something like an interface card, which will contain all the properties of your card.
Now you have your card array in your CardList. Let’s take a look at the new code in your card list component.
<app-card *ngFor="let card of cards"></app-card>
An attribute name that starts from an asterisk. What does it mean? It’s a default convention for naming Angular structural directives. Structure directives control the structure of your template. The asterisks here is actually “syntax sugar,“. But for your current example, its enough to understand what will happen when you add it to your component. So ngFor a repeater directive and it will repeat your app card for every element in the array of cards. If you look at the browser, you see this next:
Something is not right; you have your array of cards, but you are getting an empty page.
You define your array of cards on the AppComponent level, But you haven’t passed it to CardList input. Let’s edit your AppComponent template to do that.
<app-card-list [cards]="cards"></app-card-list>
This syntax – The attributes in the square brackets – tells angular that you would like to one-way bind your component variable cards to your Card List component [cards] input. As soon as you do that, you get this:
Of course, you want to display the actual contents of your card array, and for that, you need to pass the card object to the card component as well. Let’s extend your Card List component:
<app-card *ngFor="let card of cards" [card]="card"></app-card>
And if you look in the browser right now, you’ll get the next error in the JS console: Can’t bind to ‘card’ since it isn’t a known property of ‘app-card’ .
. Angular is telling us that you still need to define your input in the Card component. So you can edit thusly:
import {Component, Input, OnInit} from '@angular/core';
[...]
export class CardComponent implements OnInit {
@Input() card:any;
[...]
And let’s add your card text property to the Card component template:
[...]
<p>{{ card.text }}</p>
[...]
Let’s see how it works now:
Looks fine, but the styling is a little off. Let’s fix that by adding a new style to card.component.css :
.card {
margin-top: 1.5rem;
}
And now it looks better:
Component Communication
Let’s add a New Card Input component that will allow you to do add notes:
ng g component NewCardInput
create src/app/new-card-input/new-card-input.component.scss (0 bytes)
create src/app/new-card-input/new-card-input.component.html (33 bytes)
create src/app/new-card-input/new-card-input.component.spec.ts (672 bytes)
create src/app/new-card-input/new-card-input.component.ts (300 bytes)
update src/app/app.module.ts (593 bytes)
And add this next to its template:
<div>
<div>
<input placeholder="Take a note...">
</div>
</div>
Next, add this to the component decorator:
[...]
@Component({
selector: 'app-new-card-input',
[...]
host: {'class': 'col-4'}
})
[...]
And add your new component to the AppComponent template:
[...]
<div>
<div>
<app-new-card-input></app-new-card-input>
</div>
</div>
<app-card-list [cards]="cards"></app-card-list>
Let’s take a look at the browser.
The problem is that your new component is not doing anything. Let’s make it work – by adding a variable that will hold your new card:
[...]
export class NewCardInputComponent implements OnInit {
[...]
public newCard: any = {text: ''};
[...]
How do you populate it with your input? If you have worked with AngularJS before, you may know the concept of two-way data binding. Or, you might have seen it in all those fancy AngularJS demos, where you input value to input and it updates the page content for you.
Here’s an interesting tidbit: Two-way data binding is no longer with you in Angular. But that doesn’t mean you have lost access to the behavior. You already saw and used [value]=”expression”, which binds the expression to the input element’s value property. But you also have (input)=”expression”, a declarative way of binding an expression to the input elements input event. Together they can be used thusly:
<input [value]="newCard.text" (input)="newCard.text = $event.target.value">
So, every time your newCard.text value changes, it’ll be passed to your component input. And every time the user inputs data into your input and the browser outputs input $event, you assign your newCard.text to the input value.
One more thing before you implement it: This input looks like a little much, doesn’t it? Actually, Angular gives us a little syntax sugar for it, which you can use here, so started from a different angle to explain how this sugar works.
<input placeholder="Take a note..." [(ngModel)]="newCard.text">
This syntax,( [ ] ), called banana in a box or ngModel, is the Angular directive that takes care of getting value out of events and all that. So you can just write a simpler code that takes your value and binds it to both the value of the input and your variable in code.
Unfortunately, after you added ngModel, you are getting the error, Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’. You need to import ngModel to your AppModule. But from where? If check the documentation, you can see that it’s in the Angular Forms module. So you need to AppModule thusly:
[...]
import {FormsModule} from "@angular/forms";
@NgModule({
[...]
imports: [
BrowserModule,
FormsModule
],
[...]
Working with native events
So you have your variable populated, but you still, need to send that value to the card list in AppComponent. For communicating data to the component Angular, you must have input. It seems that to communicate data outside the component, you have output, and you use it, in the same way, you would use input— import it from the Angular code and use a decorator to define it:
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
[...]
export class NewCardInputComponent implements OnInit {
[...]
@Output() onCardAdd = new EventEmitter<string>();
[...]
}
But there is more than just output; you also define something called EventEmitter because the component output is supposed to be an event, but you shouldn’t think about it the same way you did those old JavaScript events. They aren’t bubbles. You don’t need to call preventDefault in every event listener. To send data from the component, you should use its payload. So you need to subscribe to the events—how do you do that? Let’s change the AppComponent template:
<app-new-card-input (onCardAdd)="addCard($event)"></app-new-card-input>
You are also binding an expression to the event onCardAdd, just as you mentioned in our NewCardInput component. Now you need to implement the addCard method on your AppComponent.
[...]
export class AppComponent {
[...]
addCard(cardText: string) {
this.cards.push({text: cardText});
}
But you’re still not outputting it from anywhere. Let’s try to make it happen when the user hits the enter key. You need to listen for the DOM keypress event in your component as well as output the Angular event triggered by that. For listening to DOM events, Angular gives you the HostListener decorator. It’s a function decorator that takes the name of a native event you want to listen for as well as the function Angular wants to call in response to it. Let’s implement it and discuss how it works:
import {Component, EventEmitter, OnInit, Output, HostListener} from '@angular/core';
[...]
export class NewCardInputComponent implements OnInit {
[...]
@HostListener('document:keypress', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.code === "Enter" && this.newCard.text.length > 0) {
this.addCard(this.newCard.text);
}
}
[...]
addCard(text) {
this.onCardAdd.emit(text);
this.newCard.text="";
}
[...]
So, if the document:keypress event happens, you check that the key pressed was Enter and your newCard.text has something in it. After that, you can call your addCard method, in which you output Angular onCardAdd with text from your card and reset the card text to an empty string so the user can continue to add new cards without editing the old card’s text.
Working with Forms
There are a couple of approaches to working with forms in Angular—one is template-driven and you are already using the most valuable part of it: ngModel for two-way binding. But forms in Angular are not only about model values but also about validity. Currently, you check for the validity of NewCardInput in your HostListener function. Let’s move it to a more template-driven form. For that, you can change the template for your component:
<form novalidate #form="ngForm">
<input placeholder="Take a note..." name="text" [(ngModel)]="newCard.text" required>
</form>
Here’s another syntax sugar from Angular. The hash #form is a template reference variable that you can use to access your form out of your code. Let’s use it to make sure you actually use the required attribute validation instead of the manual check on value length:
import {Component, EventEmitter, OnInit, Output, HostListener, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';
[...]
export class NewCardInputComponent implements OnInit {
[...]
@ViewChild('form') public form: NgForm;
[...]
@HostListener('document:keypress', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.code === "Enter" && this.form.valid) {
[...]
One more new decorator is here: ViewChild. Using that, you can access any element marked by template reference value—in this case, your form, as well as you actually, declare it as your Component public variable form, so you can write this.form.valid.
Working with template-driven forms is absolutely the same as you did before with simple HTML forms. But if you need something more complex, there is a different kind of form for that case in Angular: reactive. You’ll cover what they react on after converting your form. For that, let’s add a new import to AppModule.
[...]
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
[...]
imports: [
[...]
ReactiveFormsModule,
]
[...]
Reactive forms are defined in code instead of template-driven forms, so let’s change the NewCardInput component code:
[...]
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
[...]
export class NewCardInputComponent implements OnInit {
[...]
newCardForm: FormGroup;
constructor(fb: FormBuilder) {
this.newCardForm = fb.group({
'text': ['', Validators.compose([Validators.required, Validators.minLength(2)])],
});
}
[...]
if (event.code === "Enter" && this.form.valid) {
this.addCard(this.newCardForm.controls['text'].value);
[...]
addCard(text) {
this.onCardAdd.emit(text);
this.newCardForm.controls['text'].setValue('');
}
In addition to importing new modules, some new things are happening here. First of all, you are using dependency injection for FormBuilder on your constructor and also building your form with it. The text there is a name of your field, an empty string is the initial value, and Validators.compose obviously allows you to combine multiple validators on a single field. You use
.value and .setValue(”) to access value for your field.
Let’s look at your markup for this new way of working with forms:
<form [formGroup]="newCardForm" novalidate>
<input placeholder="Take a note..." name="text" formControlName="text">
</form>
You are using FormGroupDirective to tell Angular what form group Angular needs to look in for its definition. By using formControlName, you are telling Angular what field in the reactive form you should use.
For now, the main difference between the previous approach with template-driven forms and the new approach with reactive forms is in more coding on the reactive side. Is it really worth it, if you don’t need to define the form dynamically?
It absolutely is. To understand how it may be helpful, let’s discuss why this approach is called “reactive” in the first place.
Let’s start by adding additional code to your NewCardInput component constructor:
import { takeWhile, debounceTime, filter } from 'rxjs/operators';
[...]
this.newCardForm.valueChanges.pipe(
filter((value) => this.newCardForm.valid),
debounceTime(500),
takeWhile(() => this.alive)
).subscribe(data => {
console.log(data);
});
Open the browser and developer tools console, and watch what will happen when you input new value into your input
RxJS
So what’s actually happening here? You are seeing RxJS in action. Let’s discuss it. I guess you all know at least something about promises as well as building asynchronous code. Promise handling a single event. You ask the browser to make POST, for example, and it returns you a promise. RxJS operates with Observables, which handle streams of events.
Think about that like this: You have just implemented code that is called on every change of your form. If you process user changes with promises, only the first user change will be processed before you need to resubscribe. The Observable, at the same time, is able to process every event in a virtually endless stream of “promises.” You can break that by getting some error along the way or by unsubscribing from the Observable.
What is takeWhile here? You are subscribing to your Observables in your components. They are used in different parts of your app, so they may be destroyed along the way—for example, when you use components as pages in your routing. But while the promise in place of the Observable will run only a single time and will be disposed after that, the Observable is built to last as long as the stream is updating and you don’t unsubscribe. So your subscription needs to be unsubscribed (if you are not looking for memory leaks) like this:
const subscription = observable.subscribe(value => console.log(value));
[...]
subscription.unsubscribe();
But in your app, you have a lot of different subscriptions. Do you need to do all that boilerplate code? Actually, you can cheat and use the takeWhile operator. By using it you make sure that your stream will stop emitting new values as soon as this.alive becomes false and you just need to set that value in the onDestroy function of your component.
Summary
So this was your first Angular 5 App. In this article, you get to know about Angular 5, Typescript and Angular CLI as well as how to build your app in Angular 5. With the help of this, you can learn App composition in angular, component communication and work with native events as well as Angular forms.
It will be continued with Connecting Angular with Firebase in the next article.
If you want to develop an app with angular or any other technology and it seems difficult, there is no issue Codersera is here to help you by providing the top coder for your project:- Click here to Hire A Coder
And if you belong to the ones who are passionate about coding, Codersera can give you the opportunity to work on interesting and challenging projects. All you need to do is:- Click here to Apply As Coder
Source: InApps.net
List of Keywords users find our article on Google:
angular |
angular 5 |
ngfor |
angular io |
angular input |
angularjs directive |
rubymine |
tsconfig |
angular ecommerce |
ng-model in angularjs |
angular form array |
angular 5 search |
search in angular 5 |
angular 7 tutorial |
html element must have a lang attribute |
angular reload page |
angular 5 example |
getting started with angular |
angular 5 basics |
angular development |
get started angular |
angular recruitment |
angular cli npm |
tsconfig.json |
angular ngmodel |
angular input default value |
localhost 4200 |
tslint |
ngmodel |
angular scss |
update angular cli |
angular module |
angular software developer |
angular app development |
angular get started |
is not a known element angular |
jetbrains jobs |
angularjs select |
jetbrains rubymine |
npm install angular cli |
angular tour of heroes |
protractor typescript |
tsconfig json |
jetbrains wiki |
angualr |
appcard |
angular 5 application |
protractor tutorial |
ngoninit |
angular ngfor |
protractor tutorial for beginners |
ng generate |
ng serve |
ngfor angular |
angular index html |
angular navbar |
angular schematics |
protractor angular tutorial |
angularjs if |
angular cli |
call method from one component to another component angular 4 |
ul li responsive |
list markup |
angularjs expert |
html lang attribute multiple languages |
angular 5 tutorial |
intellij not recognizing imports |
install angular 5 |
cardworks jobs |
mission angular |
protractor framework github |
angularjs ng for |
learn angular 5 |
div.html not working |
protractor angular 6 tutorial |
angular json |
angular getting started |
localhost:4200/ |
youtube angular tutorial |
protractor angular 8 tutorial |
angular 1.5 |
github node gitignore |
ngfor in angular |
angular get element by class |
template ecommerce angular |
angular tutorial |
intellij vs webstorm |
localhost: 4200 |
ngoninit angular |
yarn scss |
json angular |
angular ngoninit |
angular 2 ngfor |
angular bootstrap responsive navbar |
card5 vision software |
angular 1.5 tutorial |
angular card |
angular portfolio template |
text repeater app |
angular if else in html |
angular tutorial step by step |
text editor angular |
angular editor |
ng select bind value |
webpack devserver |
twitter bootstrap tutorial |
webpack in angular |
update angular 5 to 6 |
yarn sass |
check angular cli version |
text editor for angular |
oninit |
angular empty |
intellij gitignore |
npm install ng |
agular |
ng angular |
ng generate component |
angular new project |
angular cli version list |
navbar expand md |
angular host css |
angular2 http json |
ide for angular |
npm livereload |
angular protractor tutorial |
angular replace |
could not find a declaration file for module |
webpack-dev-server npm |
angular 7 tutorial for beginners |
angular guide |
angular text editor |
bootstrap input placeholder color |
ngfor use in angular |
favicon meta tag |
angularjs web application development |
angular for mobile app development |
angular mobile development |
create angular project with scss and routing |
can’t bind to ‘ngmodel’ since it isn’t a known property of ‘input’. |
vendors.bundle.js |
angular formbuilder file upload |
tslint.json |
model driven forms in angular |
github angular components |
gitignore angular |
angular is not a known element |
gitignore for angular |
blog jetbrains |
react gitignore |
how does angular work |
property styleext is not allowed |
ng serve not working |
polyfill npm |
if is an angular component, then verify that it is part of this module. |
touch me yarn |
angular directive not working |
ng-repeat not working |
has incorrect peer dependency |
ngmodel not working |
angular 5 github |
cannot find module ‘react’ or its corresponding type declarations. |
npm readme template |
index.d.ts |
angular 5 components |
input value angular |
ng repeat index |
angular @input |
jetbrains typescript |
json editor angular |
angular ng repeat |
livereload github |
rename angular component vscode |
webstorm code with me |
angular rename component vscode |
jetbrains html editor |
@input in angular |
angular 5 tutorial deutsch |
angular check if mobile |
angular json styles |
webstorm angular |
angular input value |
angular.io |
guided tour angular |
angular let |
angular version 2 |
get value of input angular |
protractor icon |
@input angular |
angular if |
error template parse errors |
gitkeep |
npm karma |
angular cli npm install |
angularjs reload page |
coc-tslint |
get input value angular |
get json angular |
ng-repeat array |
vscode search file in node_modules |
angular cli wiki |
angular find object in array |
angular ng model |
angular watch input change |
how to rename all variables in vscode |
intellij editorconfig |
jetbrains phpstorm |
ng model angularjs |
ngfor number of times |
npm eventemitter |
angular website templates |
how to rename a component in angular |
protractor auto software |
angular 5 output |
angular 5 website templates |
vscode gitignore |
angular schematics tutorial |
angularjs jobs |
json angularjs |
json in angular |
ng create component |
npm @angular/core |
pegas md |
–cli-input-json |
angular json to object |
angular tag input |
angular valuechanges previous value |
template angular ecommerce |
angle brackets for profile structures |
angular dev kit |
angular js jobs |
angular replace all |
editor in angular |
event.target.value |
file to base64 angular |
ide error occurred intellij |
ng-bootstrap navbar |
profile readme template |
angular array |
angular directive get input value |
ng add component |
ng for in angular |
angular 2 json |
angular heroes |
angular.json |
intellij webstorm |
localhost:4200 |
node 304 build |
polyfills in angular |
webstorm git changes |
yarn install node-sass error |
@angular/core |
angular form json |
angular get element by tag |
angular is not defined angularjs |
angular mobile app tutorial |
global is not defined angular |
navbar angular |
[ngmodel] |
angular center component |
angular typed forms |
center everything in a div |
h1 webdevelopment |
ng-serve |
protractor element |
angular 1.5 component |
angular 5 node version |
angular backend tutorial |
angular ecommerce template |
angular form from json |
angular js directive |
angularjs json |
inputs.conf |
ngmodel angular |
tutorial angular 12 |
upgrade angular 5 to 6 |
webstorm run configuration |
angular 2 website templates |
angular 5 website templates free |
angular cli version check |
angular component tutorial |
angular constructor |
angular generate component without spec |
angular on input change |
angularjs element |
event emitter angular |
how long does it take to learn angular js |
rename variable vscode |
angular 4 navbar bootstrap |
angular json form |
angular-cli.json |
intellij git ignore |
karma angular |
typings.d.ts |
webstorm react |
angular 9 e2e testing |
angular ngfor array of objects |
angular website template |
as in angular |
bootstrap 5 profile card |
find and replace intellij |
framework 7 tutorial |
get value from form angular |
karma webpack |
ng for in angular 8 |
ng-select angular |
npm3 |
text editor in angular |
angular cli add module |
angular dev |
bootstrap navbar align right |
browsermodule has already been loaded |
form value angular |
how old you have to be to work at wawa |
ng serve port |
ng-conf |
reload directive angularjs |
twitter bootsrap tutorial |
angular cli 10 |
angular ecommerce tutorial |
angular framework tutorial |
angular without cli |
angularjs ng model |
learn angularjs from scratch |
qctutorials |
readme getting started |
typescript d.ts |
angular 2 select placeholder |
angular input events |
angularjs menu |
check angular version command |
constructor in angular |
jetbrains logos |
npm install sass global |
protractor conf |
webstorm |
angular 7 game development |
angular 9 tutorial for beginners |
angular bind variable to input |
angular cli version |
angular core |
angular if else |
new project angular cli |
ng repeat angular |
npm install peer dependency |
target _blank angular |
update angular 4 to 5 |
angular 5 deep linking |
angular app template free |
angular heroes tutorial |
angular input focus |
angular js 1.0 |
angular library cannot find module |
angular touch |
angular ui bootstrap |
angullar |
check angular version |
coded ui tutorial |
error: cannot find module ‘webpack-cli/package.json’ |
form io angular |
gitignore idea |
ngfor let variable |
preface app |
protractor games |
protractor near me |
sugar bytes |
text in angular |
website templates angular |
angular ! |
angular 7 website templates free |
angular cli 9 |
angular http get |
angular image src |
angular js demos |
angular parse |
angularjs tutorialpoint |
bootstrap 4 cards template |
bootstrap ecommerce auto parts template |
bootstrap navbar fixed top center |
create module in angular |
live server webstorm |
localhost:4200, |
new date in angular |
ng bootstrap card |
npm install webstorm |
sass boilerplate |
style width angular |
webpack dev server |
add model in angular |
angular 12 angular.json |
angular 2 admin template |
angular 5 project |
angular bootstrap card |
angular clear input file |
angular index.ts |
angular input on change |
angular io style guide |
angular ioc |
angular typings.d.ts |
angular version command |
directive in angular 8 |
ng generate directive |
node_modules angular |
react native clear textinput |
scss tutorial angular |
tslint fix |
vscode rename variable |
yarn add peer dependency |
angular cli 8 |
angular define array |
angular forms npm |
angular if style |
angular input function with parameters |
angular module template |
angular ng if |
angular ng-class |
build angular app from scratch |
how would you make use of this directive in markup based on its selector value |
install angular cli |
intelij replace |
javascript inline if |
root touch up tutorial |
yarn fix peer dependencies |
angular $oninit |
angular 4 tutorial |
angular 8 tutorial |
angular 8 tutorial for beginners step by step |
angular base component |
angular check version |
angular cli 13 |
angular cli generate project |
angular cli get version |
angular cli update |
angular component documentation |
angular decorator |
angular generate component |
angular get element |
angular ide online |
angular input element |
angular search input |
angularjs ecommerce template |
angularjs factory |
coangular |
ecommerce angular |
error could not find module angular devkit build angular |
intellij command line is too long |
ng create project |
ngfor index |
ngfor index angular 2 |
protractor page object model |
reload asterisk |
vim align |
webpack cli |
webpack sass |
website template angular |
windows update error 643 |
angular 10 tutorial for beginners |
angular focus input |
angular get form data |
angular update input |
compile angular project |
custom_elements_schema |
find angular version |
gitignore syntax |
how angular works |
node js saas boilerplate |
react native text input placeholder |
style if angular |
tsconfig module |
webpack 5 boilerplate |
website angular template |
webstorm tutorial |
yarn add scss |
angular create object |
angular net core |
angular template switch |
angular template variable |
angular this |
angular y javascript |
can’t bind to ngmodel since it isn’t a known property of input |
create angular application from scratch |
create component in angular 6 |
directive angularjs |
ecommerce website in angular |
http get angularjs |
http localhost 4200 |
input variable angular |
margin-top bootstrap |
navbar nav center bootstrap 4 |
ng component create |
ngfor with index |
page object model protractor |
version angular cli |
what is an angular module |
yarn requires node.js 4.0 or higher to be installed. |
angular 2 cli |
angular cli generate component |
angularjs with webpack |
how to angular |
index angular |
input in angular |
install angular |
intellij auto import |
polyfills angular |
yarn install from lockfile |
text-align center not working |
what is webstorm |
angular ide |
angular ng template |
create webpack app |
recompiles |
angular expert |
angular ui development |
property styling packages |
angularjs mobile app development |
angular vs angularjs |
angular website development |
getting started guide |
angularjs development service |
angularjs development company |
Let’s create the next big thing together!
Coming together is a beginning. Keeping together is progress. Working together is success.