Mastering Angular Components
eBook - ePub

Mastering Angular Components

Build component-based user interfaces using Angular, 2nd Edition

Gion Kunz

Share book
  1. 402 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Mastering Angular Components

Build component-based user interfaces using Angular, 2nd Edition

Gion Kunz

Book details
Book preview
Table of contents
Citations

About This Book

Develop modern user interfaces using Angular 6 and its component-based architecture.

Key Features

  • Build better web applications with highly scalable concepts using Angular
  • Learn new ways to design your web applications
  • Build a fully functional web application that lets you tackle real-world user interface problems using Angular components

Book Description

Angular framework embraces a mature user interface (UI) component architecture, a powerful tool when developing scalable application interfaces. The simple and deterministic design of Angular components supports you in building large and scalable component-based applications.

Mastering Angular Components covers a new holistic way of thinking about UI development, and helps you discover the power of Angular 6 components through various examples. The book starts with an introduction to component-based user interfaces and how Angular 6 manages this concept. Following a step-by-step approach, you will build a fully functional task-management application using Angular. You'll start with basic layout components, adding some core task-management components before completing the first draft of your application. You will then move on to working through a refactoring exercise in order to learn how to enhance the way you deal with states and data. Once you have got to grips with all this, you will study how to make use of the Angular router within your application.

By the end of this book, you will be able to constantly refine the functionality of your application and create components that render SVG graphics, add a time-tracking feature, visualize data using third-party library Chartist, and even create a plugin architecture using Angular components.

What you will learn

  • Use TypeScript to create Angular 6 components
  • Leverage component composition to solve complex UI requirements
  • Build an architecture using pure components and container components
  • Explore the basics of RxJS observable streams and use them to build your application reactively
  • Communicate between components using child queries
  • Implement the Angular router to make your application navigable
  • Build reusable and dynamic graphical content using Angular components and SVG
  • Integrate third-party libraries such as Moment.js and Chartist into your existing Angular application

Who this book is for

Mastering Angular Components is for you if you are an Angular developer who already has a good understanding of basic frontend web technologies such as JavaScript, HTML, and CSS.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on ā€œCancel Subscriptionā€ - itā€™s as simple as that. After you cancel, your membership will stay active for the remainder of the time youā€™ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlegoā€™s features. The only differences are the price and subscription period: With the annual plan youā€™ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, weā€™ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Mastering Angular Components an online PDF/ePUB?
Yes, you can access Mastering Angular Components by Gion Kunz in PDF and/or ePUB format, as well as other popular books in Informatique & Programmation en JavaScript. We have over one million books available in our catalogue for you to explore.

Information

Year
2018
ISBN
9781788295581

Thinking in Projects

It's time to think bigger. So far, we've created everything within our application around the concept of a simple task list. However, we want to build something bigger than that. Users should be able to organize their tasks into projects. Within this chapter, we're going to introduce a frame around our task list and make it feel like a full-blown application. With the introduction of a project component, the main navigation, tabbed interfaces, and a user area, we are moving a big step closer to our final application look.
We will create a reusable in-place editor component, which we will put into action on many existing areas within our application. With the help of this editor, the user experience of our system will increase tremendously, and our users will start to feel the underlying reactive architecture.
During this chapter, we will also create a commenting system that we build in a way that allows us to place it anywhere we'd like for our users to put comments.
Application security and proper user management are not within the scope of this book. However, we're going to create a dummy user service that will help us simulate a logged-in user. This service will be used by the commenting system, and we'll refactor our existing component to make use of it too.
We'll cover the following topics in this chapter:
  • Introduction of a new project component and additional container components
  • Two new RxJS operators called switchMap and take
  • Creating a tabbed interface component for project detail navigation
  • Using content projection to create a navigation UI component
  • Using contenteditable to create an in-place editor
  • Using @HostBinding and @HostListener to bind component members to host element properties and events
  • Obtaining view elements using the @ViewChild decorator
  • Performing DOM operations by using the ElementRef DOM abstraction
  • Creating a commenting system that allows us to gather user comments in different areas of our application
  • Summarizing a simple pipe to format relative time intervals using the third-party library Moment.js
  • Creating an editor that enables users to edit text fields in-place

Moving into projects

Within this topic, we're going to implement the changes needed to move our simple task list into a structure that is organized by projects. For this purpose, we need to modify the main layout of our components as well as introduce a new component that represents our projects.

Project service

First, let's update our application model to include project data. For this, we're going to create a new model for a project as well as update the model of our tasks to add a project ID.
Open up the src/app/model.ts file and apply the following changes:
export interface Task {
readonly id?: number;
readonly projectId?: number;
readonly title: string;
readonly done: boolean;
}

export type TaskListFilterType = 'all' | 'open' | 'done';

export interface Project {
readonly id?: number;
readonly title: string;
readonly description: string;
}
Each task is now including a reference to a project. The project entities are consisting of an ID, individual title, and description property. Let's also update our in-memory web API database. Open the src/app/database.ts file and apply the following changes:
import {InMemoryDbService} from 'angular-in-memory-web-api';
import {Project, Task} from './model';

export class Database implements InMemoryDbService {
createDb() {
const projects: Project[] = [
{id: 1, title: 'My first project', description: 'This is your first project.'},
{id: 2, title: 'My second project', description: 'This is your second project.'}
];

const tasks: Task[] = [
{id: 1, projectId: 1, title: 'Task 1', done: false},
{id: 2, projectId: 1, title: 'Task 2', done: false},
{id: 3, projectId: 1, title: 'Task 3', done: true},
{id: 4, projectId: 1, title: 'Task 4', done: false}
];

return {projects, tasks};
}
}
We've added two projects to our database as well as updated all the tasks to include a reference to the first of the two projects.
Now, we are going to need a service to access our projects, and we should also update our task service to include a method that allows us to query for tasks that belong to a specific project.
First, let's apply the changes to the existing task service. Open up the src/app/tasks/task.service.ts file and implement the following changes. Effective changes are marked in bold, and the ellipsis character is indicating more code that is irrelevant for the changes to be applied:
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {BehaviorSubject} from 'rxjs';
import {map} from 'rxjs/operators';
import {Task} from '../model';

@Injectable()
export class TaskService {
ā€¦

getProjectTasks(projectId: number) {
return this.tasks
.asObservable()
.pipe(
map((tasks) => tasks.filter((task) => task.projectId === projectId))
);
}
}
The added getProjectTasks method is providing a mapped observable that takes our source tasks subject and maps each tasks array to produce a filtered tasks array that only includes tasks of a specific project.
Alright, now we need to create a new service that allows us to obtain information about the projects from our in-memory web API database. Let's use the Angular CLI to create a new service:
ng generate service --spec false project/project
The Angular CLI should have created our service on the path src/app/project/project.service.ts. Let's open that file and replace its content with the following code:
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {BehaviorSubject, Observable, combineLatest} from 'rxjs';
import {map} from 'rxjs/operators';
import {Project} from '../model';

@Injectable()
export class ProjectService {
private projects = new BehaviorSubject<Project[]>([]);
private selectedProjectId = new BehaviorSubject<number>(1);
private selectedProject: Observable<Project>;

constructor(private http: HttpClient) {
this.loadProjects();
this.selectedProject = combineLatest(this.projects, this.selectedProjectId)
.pipe(
map(([projects, selectedProjectId]) =>
projects.find((project) => project.id === selectedProjectId)
)
);
}

private loadProjects() {
this.http.get<Project[]>('/api/projects')
.subscribe((projects) => this.projects.next(projects));
}

selectProject(id: number) {
this.selectedProjectId.next(id);
}

getSelectedProject() {
return this.selectedProject;
}
}
Let's discuss the preceding code changes briefly. Our project service contains three members:
  • projects: BehaviourSubject<Project[]>
    The projects member behaviour subject is emitting our whole project list once loaded from our database. This subject is the basis for all operations within our service.
  • selectedProjectId: BehaviourSubject<number>
    Since we will need to know which of the projects is currently selected within our application, we need to store this information in our service. We're using a behaviour subject for emitting the currently selected project ID. This allows us to simply emit a project ID through selectedProjectId if we wish to select a given project.
  • selectedProject: Observable<Project>
    The selectedProject observable will always emit the currently selected project. We'll make use of combineLatest to make sure if either projects or selectedProjectId emits a change. We will re-emit the updated, selected project through the selectedProject observable stream.
Within the constructor of our service, we're first calling the loadProjects method to do the HTTP call to our in-memory web API database to obtain the list of projects. Within the loadProjects method, we're sticking to the same pattern from our task service. We're subscribing to the HTTP service observable and emitting the resulting items through our internal projects subject.
After executing the loadProjects method within our constructor, we will create the selectedProject observable. We will use combineLatest, which we've discussed already in the previous chapter, to combine the projects and the selectedProjectId subjects into a single observable stream. Whenever one of those two input observables emits an event, combineLatest will combine the latest result of both input observables into a single item that is emitted through the output observable stream. We're using the map operator to extract the selected project from the list of projects and returning it as an item into the observable output stream.
Finally, the selectProject method is merely emitting the new project ID through the selectedProjectId subject. Since we're using this subject within the selectedProject observable created with combineLatest, this change will cause the selectedProject observable to re-emit the currently selected project.
As the last step, we need to add our new service to the app module providers. Let's open the src/app/app.module.ts file and apply the following changes:
ā€¦
import {ProjectService} from './proje...

Table of contents