How to Create Angular Apps Step by Step
December 21, 2021Introduction
Good day to all of our dear friends and accidental bypassers. The theme of our today’s article is how to create an app with Angular. And, first off, let’s emphasize that Angular is one beast of a TypeScript-based open-source web application framework and it takes place as one of the web-development mainstays that are absolutely justified.
We will take a closer look at the actual process of creating an Angular app to display that this process can be not only pleasant in its outcome but also simple and understandable even for a person with no prior experience in Angular app creation. Let’s get to the first point of our plan, which explains what makes Angular such a brilliant framework.
Things to Know about Angular
Angular is a TypeScript-based open-source framework, whose main purpose is developing web applications. But where Angular really shines is the creation of client applications and it is regarded as one of the best tools when it comes to single-page apps development as well.
Angular community consists of more than 18 million users and that number is simply impressive.
A big part in this is played by tools and setup that Angular possesses: RxJS, Angular CLI and different code editors that support the framework.
RxJS is a reactive programming library that is pretty crucial when it comes to working with Angular. RxJS’ main aim is to handle asynchronous data with multiple events and by doing that this reactive programming library allows engineers to build multiple channels of data exchange to ease the consumption of resources. So, basically, RxJS is similar to a conveyor for JavaScript codes, as it allows parallel and continuing execution of events in a manner, independent from one another, and without waiting for one event to happen to complete another. And although RxJS’ learning curve might seem a bit high, it is worth every penny.
The second great tool in Angular’s arsenal is the Angular command-line interface (or just CLI for short). Favored by many an engineer, Angular CLI is easy to set up, quite understandable even for newcomers, is packed to the brim with different testing tools right out of the box and its commands can be described as nothing but simple. But let’s take a closer look at the pros and cons of Angular.
Angular Pros
1. Angular architecture is component-based and its primary architectural characteristic is the basis of components hierarchy. This fact allows developers to achieve a higher code quality by making the overall code more accessible and understandable by encapsulating all of the components with their functionality.
2. All Angular components are reusable. And this advantage is a direct outcome of the previous one because the previously mentioned encapsulation of components makes them exceptionally self-sufficient. It also allows developers to reuse them in different parts of their applications, making the process of developing a bit faster and more convenient.
3. Angular’s readability is off the charts. Once again due to the component-based architecture and the encapsulation. Thus, new developers, albeit new to the whole app developing a game or just new to the project, can read code in a better way and reach their plateau of productivity quicker.
4. Angular is unit-test friendly. Try and guess why it is so. Right you are, all because of the component-based structure that simplifies the quality assurance procedures even when it comes to the smallest parts of the app, which are, of course, units.
5. Angular is maintainable. It is quite easy to maintain and update the code.
6. Angular uses TypeScript. Let us get a little misconception out of the way first – it is not mandatory to use TypeScript with Angular, as it provides devs with options on how to use their libraries more efficiently, including Redux and Flux. But why use them if you can use TypeScript, which can be described as a superset for JavaScript? Yes, it has its fair share of things to nitpick and yes, you basically have to learn another language if you never worked with TypeScript, but its overall usefulness is immense. Especially if you work on an enterprise-level project, as TypeScript simply has better navigation, autocompletion, refactoring services and it helps you to spot and get rid of common mistakes while you type in the code. All in all, TypeScript is great and Angular is only better because of it.
7. Angular has long-term Google support. Also known simply as LTS, Google’s Long-Term Support means that Google is planning to stick with and further develop the Angular ecosystem.
Angular Cons
The main disadvantage of Angular is the fact that Angular is complex. Although the component-based architecture Angular possesses is great, the way in which components are managed is not, as each and every component in your app will, most likely, need dependency injections and all of them will definitely need lifecycle interfaces. And that’s not mentioning the fact that you will have to rely on third-party libraries that are quite specific when it comes to Angular. Thus, developing apps on Angular can be (bear in mind that it is a possibility and not an axiom) pretty repetitive and tiresome.
The second disadvantage worth mentioning mainly concerns new and up-and-coming developers and it is the fact that Angular’s learning curve is steep. As we have already mentioned, if you were to learn Angular from scratch, you will also need to learn TypeScript, modules, dependency injection, components, services, templates, RxJS management, etc.
Summing up, even though it can be fearsome for new developers and at times complicated for new and professional developers alike, Angular is a great tool for a variety of web app development needs and, with Google’s Long-Term Support, its future in the industry looks as bright as ever. That being said, let’s get to the metaphorical cherry on top of the cake of today’s article – an example of step-by-step Angular app development.
Step-by-step Angular App Creation
In this tutorial, we are going to create a simple Angular App on an Angular 8 basis in eleven easy steps. The steps are:
1. Angular CLI 8 installation;
2. Angular 8 Project creation;
3. Addition of Angular HttpClient;
4. UI Component Creation;
5. Routing Addition;
6. UI Building with the help of Angular Material Components;
7. Mocking a REST API;
8. Consuming the REST API with Angular HttpClient;
9. HTTP Errors Handling;
10. Pagination Addition;
11. Building and Deploying the Angular Application to Firebase.
Now, let’s get through these steps one by one.
1. Angular CLI 8 installation
The first thing we will have to do to create an Angular App is to get our Angular CLI up to speed. And that step is crucial, as Angular CLI is the official tool for Angular projects’ initializing and working. Write the following line of code into a new terminal that we have just created:
npm install -g @angular/cli
2. Angular 8 Project creation
Now we can initialize our Angular project. Use the following commands:
cd ~
ng new angular-example
Immediately after that, the CLI will send you a prompt, asking whether you’d like the addition of Angular routing. And that is just too good of an offer to decline. Right after that, the CLI will ask you which stylesheet format you would like to use and here we are going to choose the CSS option.
That decision will lead Angular to generate the files and folders required, as well as install the needed packages from npm. But that’s not all, as it will also set up the routing we have mentioned earlier automatically.
After that, we are going to go to the root folder of our project and run the local development server using these commands:
cd angular-example
ng serve
That will make our application available at the following address:
[http://localhost:4200/](http://localhost:4200/)
What we need to do is to go to this address using a web browsing of our choosing and see a beautiful, yet utterly incomplete page like this:
3. Addition of Angular HttpClient
This step is pretty easy in execution despite being command-heavy at first sight. What we need to do here is to open the src/app/app.module.ts file and make the following changes:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
What we did here is a simple act of importing the HttpClientModule and including it into the import array. This step is needed to assure the consumption of the REST API by the HttpClient.
4. UI Component Creation
As we have already mentioned, Angular Apps are made up of components. So, to do it, we open yet another new terminal and use the following line of coding:
cd ~/angular-example
ng g component home
And running these commands will display the following output in our terminal:
CREATE src/app/home/home.component.html (19 bytes) CREATE src/app/home/home.component.spec.ts (614 bytes) CREATE src/app/home/home.component.ts (261 bytes) CREATE src/app/home/home.component.css (0 bytes) UPDATE src/app/app.module.ts (467 bytes)
And that leads us to the creation of the about component by running the following command:
ng g component about
And that leads us to the src/app/about/about.component.html file and adding the following:
<p style="padding: 15px;"> This is the about page that describes your app</p>
Voila! We have just created a component, aren’t we just great? Now we can get to step number 5.
5. Routing Addition
Once again, a codding-heavy step, by a crucial one at that it will help us redirect the empty path to the home component. This, in order, will automatically redirect the first-time users of our app to its home page.
So, what we do here is running the following set of routes into our src/app/app-routing.module.ts file:
import { NgModule } 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 },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
6. UI Building with the help of Angular Material Components
Let’s start by going to the root file of our project and adding the following line of coding:
ng add @angular/material
After that, Angular will suggest you choose a theme for the project. And, as we feel playful, let’s choose the Indigo/Pink option. That will not be the end of it and the prompt will also ask us whether we would like to set up HammerJS for gesture recognition, as well as browser animations for Angular Material. Here we are going to simply press Enter and be on our merry way, as after that we will need to open the src/app/app.module.ts file and add the following imports:
import { MatToolbarModule
MatIconModule
MatCardModule
MatButtonModule
MatProgressSpinnerModule } from '@angular/material';
What we are doing by this is importing the modules for the following Material Design components:
1. MatToolbar – for headers, titles, or actions containers;
2. MatCard – in order to provide a content container for text, photos, and actions in the context of a single subject;
3. MatButton – for a native <button> or <a> element that is enhanced with styling and ink ripples of Material Design;
4. MatProgressSpinner – in order to provide a progress and activity circular indicator.
And after the modules are imported, we can add those modules into the import array by running the following lines of code:
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
MatToolbarModule,
MatIconModule,
MatButtonModule,
MatCardModule,
MatProgressSpinnerModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Now, we are going to open the src/app/app.component.html file and update it with the following code lines:
<mat-toolbar color="primary"> <h1> My Angular Store </h1> <button mat-button routerLink="/">Home</button> <button mat-button routerLink="/about">About</button></mat-toolbar><router-outlet></router-outlet>
This way we have added a top navigation bar with two buttons that can take our app user to the Home and About pages of our project.
7. Mocking a REST API
This step is packed with different small substeps we will have to undertake. But fear not, as they all are simple and you won’t actually spend a lot of time to complete them, although you will have to be pretty precise about your actions.
We start this step by going to a new command-line interface and installing json-server from the npm. We do this with the help of the following command:
cd ~/angular-example
npm install --save json-server
And now we need to create a server folder in our Angular project’s root folder by writing these lines:
mkdir server
cd server
Don’t leave the server folder just yet, as we still need to create a database.json file and add the following JSON object that will act as a database for our REST API server:
{
“products”: []
}
Now we need to go back to the command-line and navigate back from the server folder to install Faker.js from our npm by the following command:
cd ..
npm install faker –save
Create the generate.js file with the following coding lines:
var faker = require('faker');
var database = { products: []};
for (var i = 1; i<= 300; i++) {
database.products.push({
id: i,
name: faker.commerce.productName(),
description: faker.lorem.sentences(),
price: faker.commerce.price(),
imageUrl: "https://source.unsplash.com/1600x900/?product",
quantity: faker.random.number()
});
}
console.log(JSON.stringify(database));
After that, add the generate and server scripts we have created into the package.json file by including the following lines into our code:
"scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "generate": "node ./server/generate.js > ./server/database.json", "server": "json-server --watch ./server/database.json"
},
Next, we will go back to the command-line interface and run the generate script by using the following command:
npm run generate
And after that we are to run our freshly baked REST API by executing the command that goes like this:
npm run server
This action will allow us to send HTTP requests with the following API endpoints:
· GET /products for products getting;
· GET /products/<id> for single product getting by id;
· POST /products for new product creation;
· PUT /products/<id> for product updating by id;
· PATCH /products/<id> for partial product updating by id;· DELETE /products/<id> for product deletion by id.
8. Consuming the REST API with Angular HttpClient
Now we need to make Angular consume our REST API using HttpClient. And we start this process by creating an Angular service that will encapsulate the code, which, in turn, will allow us to consume data from our REST API server. Check our terminal and write in the following command:
ng g service api
After that what we need to do is to go to the src/app/api.service.ts file in order to import and inject HttpClient. This will be achieved by doing the subsequent actions:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private SERVER_URL = "http://localhost:3000";
constructor(private httpClient: HttpClient) { }
}
Now we need to define a get() method, which will send GET requests to our REST API endpoints:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' }) export class ApiService {
private SERVER_URL = "http://localhost:3000";
constructor(private httpClient: HttpClient) { }
public get(){ return this.httpClient.get(this.SERVER_URL); } }
At this point, we defined a product’s variable and called the get() method of the service to fetch data from the JSON REST API server. Now what we need to do is to open the src/app/home/home.component.html file to update it as you will see below:
<div style="padding: 13px;">
<mat-spinner *ngIf="products.length === 0"></mat-spinner>
<mat-card *ngFor="let product of products" style="margin-top:10px;">
<mat-card-header>
<mat-card-title>{{product.name}}</mat-card-title>
<mat-card-subtitle>{{product.price}} $/ {{product.quantity}}
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>
{{product.description}}
</p>
<img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" />
</mat-card-content>
<mat-card-actions>
<button mat-button> Buy product</button>
</mat-card-actions>
</mat-card>
</div>
Now we can proceed with step number nine.
9. HTTP Errors Handling
Start this step by going to the src/app/api.service.ts file and updating it as follows:
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private SERVER_URL = "http://localhost:3000/products";
constructor(private httpClient: HttpClient) { }
handleError(error: HttpErrorResponse) {
let errorMessage = 'Unknown error!';
if (error.error instanceof ErrorEvent) {
// Client-side errors
errorMessage = `Error: ${error.error.message}`;
} else {
// Server-side errors
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
window.alert(errorMessage);
return throwError(errorMessage);
}
public sendGetRequest(){
return this.httpClient.get(this.SERVER_URL).pipe(catchError(this.handleError));
}
}
And now we will be able to see the errors in our browser console:
This nice and easy step allows us to get down to the penultimate, tenth, step of our Angular App creation journey.
10. Pagination Addition
What we do in this step is adding the data pagination support by using the Link header of the HTTP response, which is going to be received from the REST API server. This means that we will need to instruct HttpClient to give us the full HttpResponse, instead of providing us with the response body. Use the observe option.
Start by opening the src/app/data.service.ts file and importing the RxJS tap() operator with the following command:
import { retry, catchError, tap } from 'rxjs/operators';
After that, add the following variables:
public first: string = “”;
public prev: string = “”;
public next: string = “”;
public last: string = “”;
Now we are set to add the parseLinkHeader() method in order to parse the Link header and populate the variables we have added in the previous substep:
parseLinkHeader(header) {
if (header.length == 0) {
return ;
}
if (header.length == 0) {
return ;
}
let parts = header.split(',');
var links = {};
parts.forEach( p => {
let section = p.split(';');
var url = section[0].replace(/<(.*)>/, '$1').trim();
var name = section[1].replace(/rel="(.*)"/, '$1').trim();
links[name] = url;
});
this.first = links["first"];
this.last = links["last"];
this.prev = links["prev"];
this.next = links["next"];
}
And that, in turn, allows us to safely update the sendGetRequest() with the following lines of coding:
public sendGetRequest(){
// Add safe, URL encoded _page and _limit parameters return this.httpClient.get(this.SERVER_URL, { params: new HttpParams({fromString: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {
console.log(res.headers.get('Link'));
this.parseLinkHeader(res.headers.get('Link'));
}));
}
One pulls the other, so we can now update the home component of our app. To do that, open the src/app/home/home.component.ts file to import HttpResponse:
import { HttpResponse } from '@angular/common/http';
And now we can update the subscribe() method as follows:
ngOnInit(){
this.apiService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>)=>{ console.log(res); this.products = res.body; }) }
Go back to the src/app/data.service.ts file to add the following method, which is quite similar to sendGetRequest() with a simple twist of it taking the URL to which we need to send an HTTP GET request:
public sendGetRequestToUrl(url: string){ return this.httpClient.get(url, { observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => { console.log(res.headers.get('Link')); this.parseLinkHeader(res.headers.get('Link'));
})); }
After that we can go back to the src/app/home/home.component.ts file to define the following method:
public firstPage() {
this.products = [];
this.apiService.sendGetRequestToUrl(this.apiService.first).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
console.log(res);
this.products = res.body;
})
}
public previousPage() {
if (this.apiService.prev !== undefined && this.apiService.prev !== '') {
this.products = [];
this.apiService.sendGetRequestToUrl(this.apiService.prev).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
console.log(res);
this.products = res.body;
})
}
}
public nextPage() {
if (this.apiService.next !== undefined && this.apiService.next !== '') {
this.products = [];
this.apiService.sendGetRequestToUrl(this.apiService.next).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
console.log(res);
this.products = res.body;
})
}
}
public lastPage() {
this.products = [];
this.apiService.sendGetRequestToUrl(this.apiService.last).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
console.log(res);
this.products = res.body;
})
}
And now, to finalize the tenth step we will need to open the src/app/home/home.component.html file to update the template:
<div style="padding: 13px;">
<mat-spinner *ngIf="products.length === 0"></mat-spinner>
<mat-card *ngFor="let product of products" style="margin-top:10px;">
<mat-card-header>
<mat-card-title>#{{product.id}} {{product.name}}</mat-card-title>
<mat-card-subtitle>{{product.price}} $/ {{product.quantity}}
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>
{{product.description}}
</p>
<img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" />
</mat-card-content>
<mat-card-actions>
<button mat-button> Buy product</button>
</mat-card-actions>
</mat-card>
</div>
<div>
<button (click) ="firstPage()" mat-button> First</button>
<button (click) ="previousPage()" mat-button> Previous</button>
<button (click) ="nextPage()" mat-button> Next</button>
<button (click) ="lastPage()" mat-button> Last</button>
</div>
Here we are, at the gate of the final, eleventh, step of our journey.
11. Building and Deploying the Angular Application to Firebase
Head back to the CLI. What you need is the root folder of the project, as you will need to run the following command there in order to add the Firebase deployment capability to our project:
ng add @angular/fire
The CLI will prompt you to paste in the authorization code. In order to paste it in you will need to sign into the Google account, associated with your Firebase account, where you will find the authorization code. After that is done, the CLI will prompt you to select a project, which you do. And after that, the command-line interface will create the firebase.json and .firebaserc files and update the angular.json file accordingly.
At this point, we are ready to deploy the application to Firebase by using the following command:
ng deploy
And now, our production is an asset to Firebase hosting, which also concludes the creation of our Angular App altogether, meaning that we have at our hands a crisp new app ready for usage. But each and every app needs one crucial thing – its own CMS.
How to Create a CMS for Your Angular App
The secret to creating a CMS for your Angular App faster is in using Flatlogic Platform. There are 5 short steps to build your CMS, each taking less than a minute.
1. Choose a name for your project
This one is pretty self-explanatory.
2. Choose your project’s stack
The secret to creating an Angular CMS is actually choosing it as a frontend option.
3. Choose a design for your CMS
There are five beautiful ready-made designs to pick the one you like the most.
4. Choose/create a schema editor for your CMS
There are also a couple of ready-made schemas for you. Or just create a brand-new schema from scratch.
5. Review & generate your CMS
This one is just a measure of assurance, as all you have to do is just review your choices and press the «Create Project» button.
Conclusions
As you can see, the process of creating an Angular application is quite fascinating with all the different little things you have to keep in mind. Angular’s place among the leaders of frontend frameworks is more than deserved. Have a nice day and read up on more of our articles!