100% found this document useful (1 vote)
1K views

Reactive Patterns with RxJS for Angular A practical guide to managing your Angular application s data reactively and efficiently using RxJS 7 Lamis Chebbi pdf download

The document is a guide titled 'Reactive Patterns with RxJS for Angular' by Lamis Chebbi, focusing on managing Angular application data reactively using RxJS 7. It covers various reactive programming concepts, including fetching data as streams, error handling, and testing RxJS observables. The book is aimed at Angular developers with a beginner-level understanding of Angular, RxJS, and TypeScript.

Uploaded by

wehrishuttye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
1K views

Reactive Patterns with RxJS for Angular A practical guide to managing your Angular application s data reactively and efficiently using RxJS 7 Lamis Chebbi pdf download

The document is a guide titled 'Reactive Patterns with RxJS for Angular' by Lamis Chebbi, focusing on managing Angular application data reactively using RxJS 7. It covers various reactive programming concepts, including fetching data as streams, error handling, and testing RxJS observables. The book is aimed at Angular developers with a beginner-level understanding of Angular, RxJS, and TypeScript.

Uploaded by

wehrishuttye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

Reactive Patterns with RxJS for Angular A

practical guide to managing your Angular


application s data reactively and efficiently
using RxJS 7 Lamis Chebbi download
https://textbookfull.com/product/reactive-patterns-with-rxjs-for-
angular-a-practical-guide-to-managing-your-angular-application-s-
data-reactively-and-efficiently-using-rxjs-7-lamis-chebbi/

Download more ebook from https://textbookfull.com


We believe these products will be a great fit for you. Click
the link to download now, or visit textbookfull.com
to discover even more!

Reactive Programming with Angular and ngrx: Learn to


Harness the Power of Reactive Programming with RxJS and
ngrx Extensions 1st Edition Oren Farhi (Auth.)

https://textbookfull.com/product/reactive-programming-with-
angular-and-ngrx-learn-to-harness-the-power-of-reactive-
programming-with-rxjs-and-ngrx-extensions-1st-edition-oren-farhi-
auth/

Reactive Programming with RxJS 5 Untangle your


asynchronous Javascript code 1st Edition Sergi Mansilla

https://textbookfull.com/product/reactive-programming-with-
rxjs-5-untangle-your-asynchronous-javascript-code-1st-edition-
sergi-mansilla/

Essential Angular for ASP.NET Core MVC 3: A Practical


Guide to Successfully Using Both in Your Projects 2nd
Edition Adam Freeman

https://textbookfull.com/product/essential-angular-for-asp-net-
core-mvc-3-a-practical-guide-to-successfully-using-both-in-your-
projects-2nd-edition-adam-freeman/

Learn With Angular 4 Collected Essays Angular CLI Unit


Testing Debugging TypeScript and Angular Build
Processes 2nd Edition Jeffry Houser

https://textbookfull.com/product/learn-with-angular-4-collected-
essays-angular-cli-unit-testing-debugging-typescript-and-angular-
build-processes-2nd-edition-jeffry-houser/
ng-book The Complete Guide to Angular Nate Murray

https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-nate-murray/

Angular Up and Running Learning Angular Step by Step


Shyam Seshadri

https://textbookfull.com/product/angular-up-and-running-learning-
angular-step-by-step-shyam-seshadri/

ng-book: The Complete Guide to Angular 5 Nathan Murray

https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-5-nathan-murray/

Ng Book The Complete Guide to Angular 9 Nathan Murray

https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-9-nathan-murray/

Ng Book The Complete Guide to Angular 11 Felipe Coury

https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-11-felipe-coury/
Reactive Patterns
with RxJS
for Angular

A practical guide to managing your Angular


application's data reactively and efficiently
using RxJS 7

Lamis Chebbi

BIRMINGHAM—MUMBAI
Reactive Patterns with RxJS for Angular
Copyright © 2022 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or
transmitted in any form or by any means, without the prior written permission of the publisher,
except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the
information presented. However, the information contained in this book is sold without warranty,
either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors,
will be held liable for any damages caused or alleged to have been caused directly or indirectly by
this book.
Packt Publishing has endeavored to provide trademark information about all of the companies
and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing
cannot guarantee the accuracy of this information.
Associate Group Product Manager: Pavan Ramchandani
Publishing Product Manager: Ashitosh Gupta
Senior Editor: Mark Dsouza
Content Development Editor: Divya Vijayan
Technical Editor: Shubham Sharma
Copy Editor: Safis Editing
Project Coordinator: Ajesh Devavaram
Proofreader: Safis Editing
Indexer: Rekha Nair
Production Designer: Alishon Mendonca
Marketing Coordinator: Elizabeth Varghese

First published: April 2022

Production reference: 2210422

Published by Packt Publishing Ltd.


Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

ISBN 978-1-80181-151-4

www.packt.com
To my father, who taught me diligence, perseverance, and work ethic. Thank
you for always being there to support me and lift me up.
To my mother, who taught me selflessness and doing things with love.
Thank you for your enduring encouragement during the writing of this
book.

To my brother and my sisters, for their continuous support.


-Lamis Chebbi
Contributors
About the author
Lamis Chebbi is a Google Developer Expert for Angular and an Auth0 ambassador.
She is an enthusiastic software engineer with a strong passion for the modern web. She's
the founder of Angular Tunisia, a member of the WWCode community, a speaker, a
content creator, and a trainer. She has been into Angular for the past few years and loves
to share her knowledge about Angular through participating in workshops and organizing
training sessions. ng-girls is one of the communities she supports. Empowering women
and students is one of her highest priorities. Besides Angular and the web, Lamis loves
music, traveling, chromotherapy, and volunteering. Last but not least, she's a forever
student.
I want to thank all the people that believed in me and supported me.
I am thankful for the people who helped me in the journey.
I am thankful for the people who inspired me in the journey.
About the reviewer
Dave Muellerchen is a freelancer. He loves sharing his self-taught knowledge of JavaScript
at meetups and conferences.
His passion for communities shows in his commitment to them. He is the organizer of
the Angular Hamburg Meetup and Tech Meetup Hamburg. He is also a team member
at the Angular conference in Germany (ng-de) and a Google Developer Expert for web
technologies. He streams developer content on Twitch.
Thanks to my wife, who has my back to do what I do. Thank you my sons, for the fun and the
distraction. And of course, thank you Lamis for your trust.
Anu Nagan G has worked in various corporate organizations starting from SaaS startup
[GenDeep], midsize [GAVS], Fortune 500 companies [DXC] playing various roles there
such as Technical Product Manager, Full Stack Product Lead [Angular, Java, Python,
AWS], Delivery Lead respectively in his 8 years of tenure. Currently, he is with Bounteous,
leading parallel projects such as Clinical mobile app development, Fintech marketing data
migration. Contributed to various AIOps products ZIF, Gcare in the past. He is an avid
reader, cinephile, who loves to play Guitar, makes short films with his friends.
I would like to dedicate this to my grandparents who are celebrating their 82nd anniversary,
to my wife and we are expecting. Happy birthday Hema.
Table of Contents

Preface

Part 1 – Introduction
1
The Power of the Reactive Paradigm
Technical requirements 4 The HTTP client module 7
Exploring the pillars of reactive The router module 8
programming  4 Reactive forms 13
Data streams 4 The event emitter  14
Observer patterns 5 The async pipe 15

Using RxJS in Angular and its Learning about the marble


advantages7 diagram – our secret weapon 15
Summary18

2
RxJS 7 – The Major Features
Technical requirements 20 The firstValueFrom() method 25
Exploring the bundle size The lastValueFrom() method 26
improvements  20 Empty errors 26

Reviewing the TypeScript typing Highlighting API consistency


improvements22 improvements27
Understanding the toPromise() Summary29
deprecation23
viii Table of Contents

3
A Walkthrough of the Application
Technical requirements 32 View five – the modify recipe interface 36
Our app's user stories 32 View six – the recipe details interface 37

View one – the landing page  32 Our app's architecture 38


View two – the new recipe interface 34
The components overview 38
View three – the My Recipes interface 35
View four – the My Favourites interface 36
Summary39

Part 2 – A Trip into Reactive Patterns


4
Fetching Data as Streams
Technical requirements 44 Exploring the reactive pattern
Defining the requirement  45 for fetching data 52
Exploring the classic pattern for Retrieving data as streams 53
fetching data 45 Defining the stream in your component 53
Using the async pipe in your template 54
Defining the structure of your data 45
Creating an Angular service 46 Highlighting the advantages of
Retrieving the data through a method 47 the reactive pattern 55
Injecting and subscribing to the service Using the declarative approach 55
in your component 47
Using the change detection strategy of
Displaying the data in the template 48 OnPush 56
Managing unsubscriptions 49 Wrapping up 58

Summary59

5
Error Handling
Technical requirements 62 Exploring error handling
Understanding the anatomy of patterns and strategies 63
an Observable 62 Handling error operators 64
Table of Contents ix

The catchError operator  64 Error handling in action  75


The delayWhen operator 72 Summary77

6
Combining Streams
Technical requirements 80 Exploring the declarative
Defining the requirement 80 pattern for filtering data 85
Exploring the imperative The combineLatest operator 86
pattern for filtering data 81 The declarative pattern pillars 87
Emitting a value when an action occurs 90
A look at the filter component 81
A look at the recipes list component 82 Summary94

7
Transforming Streams
Technical requirements 96 Learning about other useful
Defining the requirement 96 higher-order mapping
operators107
Exploring the imperative
pattern for autosave 97 The mergeMap operator  107
The switchMap operator  108
Exploring the reactive pattern
The exhaustMap operator  109
for autosave 100
Higher-order observables 101 Summary110
Higher-order mapping operators 101
The concatMap operator 102

Part 3 – Multicasting Takes You to


New Places
8
Multicasting Essentials
Technical requirements 114 Producer  114
Explaining Multicasting A cold observable  114
versus Unicasting 114 A hot observable  116
x Table of Contents

Exploring Subjects 118 Highlighting Multicasting


A plain Subject 119 operators123
ReplaySubject120 Summary123
BehaviorSubject  121

9
Caching Streams
Technical requirements 126 Exploring the RxJS 7
Defining the requirement 126 recommended pattern to
cache streams 133
Learning about using
the reactive pattern to Highlighting the use cases of
cache streams 127 caching streams 134
Summary135

10
Sharing Data between Components
Technical requirements 138 Step two – updating the last-selected
recipe140
Defining the requirement 138
Step three – consuming the
Exploring the reactive pattern last-selected recipe 142
to share data 139
Step one – creating a shared service 139 Highlighting other ways for
sharing data 144
Summary145

11
Bulk Operations
Technical requirements 147 The pattern in action 151
Defining the requirement 148 Learning about the reactive
Learning about the reactive pattern for tracking progress 156
pattern for bulk operations 149 Summary157
The forkJoin operator 150
Table of Contents xi

12
Processing Real-Time Updates
Technical requirements 160 Connection management 164
Defining the requirement 160 Putting the pattern into action 166

Learning the reactive pattern Learning the reactive pattern


for consuming real-time for handling reconnection 170
messages 161 Retrying the reconnection 172
The WebSocketSubject behavior 161
Summary173

Part 4 – Final Touch


13
Testing RxJS Observables
Technical requirements 178 Understanding the syntax 182
Learning about the subscribe Implementing marble tests 184
and assert pattern 178 Highlighting testing streams
Learning about the marble using HttpClientTestingModule 190
testing pattern 182 Summary192

Index
Other Books You May Enjoy
Preface
Switching to a reactive mindset is one of the biggest challenges when you start learning
Reactive programming using RxJS. I believe that the reactive mindset is gradually
achieved by learning reactive patterns and comparing the reactive way with the imperative
one to distinguish the difference and the benefits.
That's why I wrote this book, which gathers a set of reactive patterns applied in an
Angular application. Learning reactive patterns helps with managing your application's
data efficiently, writing clean and maintainable code, reacting to user changes faster, and
consequently, enhancing the user experience.
So, all that you have to do is get started!

Who this book is for


The book is for Angular developers who want to use RxJS to build reactive web
applications. This book assumes beginner-level knowledge of and experience with
Angular, RxJS, TypeScript, and functional programming concepts.

What this book covers


Chapter 1, The Power of the Reactive Paradigm, explains the fundamentals of Reactive
programming.
Chapter 2, RxJS 7 – The Major Features, focuses on the main improvements of RxJS 7.
Chapter 3, A Walkthrough of the Application, highlights the architecture and requirements
of the application that we will be building gradually.
Chapter 4, Fetching Data as Streams, explains the first reactive pattern for fetching data.
Chapter 5, Error Handling, details the error handling strategies and the reactive patterns
for handling errors.
Chapter 6, Combining Streams, explains the reactive pattern for combining streams.
Chapter 7, Transforming Streams, explains the reactive pattern for transforming streams.
xiv Preface

Chapter 8, Multicasting Essentials, focuses on the multicasting approach essentials.


Chapter 9, Caching Streams, explains the reactive pattern for caching streams.
Chapter 10, Sharing Data between Components, explains the reactive patterns for sharing
data between components.
Chapter 11, Bulk Operations, explores the reactive pattern for performing bulk actions.
Chapter 12, Processing Real-Time Updates, explores the reactive pattern for consuming
real-time updates.
Chapter 13, Testing RxJS Observables, explains the different strategies for testing reactive
patterns.

To get the most out of this book


All code examples have been tested using Angular 12 on a Windows operating system.
However, it should work with future releases too.

Please make sure you follow the prerequisites at https://angular.io/guide/


setup-local. The prerequisites include the environment setup and the technologies
needed in order to install and use Angular.
We also used the Bootstrap library to manage the application responsiveness. We used
primeng as a library of rich components and RxJS 7 as the reactive library, of course.
If you are using the digital version of this book, we advise you to type the code yourself or
access the code from the book's GitHub repository (a link is available in the next section).
Doing so will help you avoid any potential errors related to the copying and pasting of
code.
Preface xv

Download the example code files


You can download the example code files for this book from GitHub at https://
github.com/PacktPublishing/Reactive-Patterns-with-RxJS-for-
Angular. If there's an update to the code, it will be updated in the GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at
https://github.com/PacktPublishing/. Check them out!

Download the color images


We also provide a PDF file that has color images of the screenshots and diagrams used
in this book. You can download it here: https://static.packt-cdn.com/
downloads/9781801811514_ColorImages.pdf.

Conventions used
There are a number of text conventions used throughout this book.
Code in text: Indicates code words in text, database table names, folder names,
filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles.
Here is an example: "In the try block, you place your risky statements, and inside catch,
you handle the possible exceptions."
A block of code is set as follows:

behaviourSubject$.subscribe({
next: (message) => console.log(message),
error: (error) => console.log(error),
complete: () => console.log('Stream Completed'),
});

When we wish to draw your attention to a particular part of a code block, the relevant
lines or items are set in bold:

behaviourSubject$.subscribe({
next: (message) => console.log(message),
error: (error) => console.log(error),
complete: () => console.log('Stream Completed'),
});
xvi Preface

Any command-line input or output is written as follows:

$ mkdir css
$ cd css

Bold: Indicates a new term, an important word, or words that you see onscreen. For
instance, words in menus or dialog boxes appear in bold. Here is an example: "Select
System info from the Administration panel."

Tips or Important Notes


Appear like this.

Get in touch
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, email us at
[email protected] and mention the book title in the subject of your message.
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes
do happen. If you have found a mistake in this book, we would be grateful if you would
report this to us. Please visit www.packtpub.com/support/errata and fill in the
form.
Piracy: If you come across any illegal copies of our works in any form on the internet,
we would be grateful if you would provide us with the location address or website name.
Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in
and you are interested in either writing or contributing to a book, please visit authors.
packtpub.com.
Preface xvii

Share Your Thoughts


Once you've read Reactive Patterns with RxJS for Angular, we'd love to hear your thoughts!
Please click here to go straight to the Amazon review page for this
book and share your feedback.
Your review is important to us and the tech community and will help us make sure we're
delivering excellent quality content.
Part 1 –
Introduction

In this section, you will understand the importance of using the reactive paradigm in
an Angular application, as well as the new features of RxJS 7. In the third chapter, we
will introduce the application that we are going to progressively build as we go through
the book.
This part comprises the following chapters:

• Chapter 1, The Power of the Reactive Paradigm


• Chapter 2, RxJS 7 – The Major Features
• Chapter 3, A Walkthrough of the Application
1
The Power of the
Reactive Paradigm
This book is based entirely on useful reactive patterns in Angular applications. Reactive
patterns are reusable solutions to a commonly occurring problem using reactive
programming. Behind all of these patterns, there is a new way of thinking, new
architecture, new coding styles, and new tools.
I know you are impatient to write your first reactive pattern in Angular, but before doing
that, and to help you take full advantage of all the RxJS patterns and leverage the reactive
paradigm, we will start by explaining, in detail, all the fundamentals. Additionally, we
will prepare the groundwork for the following chapters. First, let's start with a basic
understanding of the reactive paradigm, its advantages, and the problems it solves. And
best of all, let's get into the reactive mindset and start thinking reactively.
We will begin by highlighting the pillars and the advantages of the reactive paradigm.
Then, we will describe the relationship between Angular and RxJS. Finally, we will explain
the Marble diagram and why it is useful.
Giving an insight into the fundamentals of the reactive paradigm is incredibly important.
This will ensure you get the basics right, help you understand the usefulness of the reactive
approach, and consequently, help you determine which situation it is best to use it in.
4 The Power of the Reactive Paradigm

In this chapter, we're going to cover the following topics:

• Exploring the pillars of reactive programming


• Using RxJS in Angular and its advantages
• Learning about the marble diagram – our secret weapon

Technical requirements
This chapter does not require an environment setup or installation steps. All the code
snippets here are just examples to illustrate the concepts. This book assumes that you have
a basic understanding of Angular and RxJS.

Exploring the pillars of reactive programming


Let's begin with a little bit of background!
Reactive programming is among the major programming paradigms used by developers
worldwide. Every programming paradigm solves some problems and has its own
advantages. By definition, reactive programming is programming with asynchronous
data streams and is based on observer patterns. So, let's talk about these pillars of reactive
programming!

Data streams
Data streams are the spine of reactive programming. Everything that might change or
happen over time (you don't know when exactly) is represented as a stream, such as data,
events, notifications, and messages. Reactive programming is about reacting to changes as
soon as they are emitted!
An excellent example of data streams is UI events. Let's suppose that we have an HTML
button, and we want to execute an action whenever a user clicks on it. Here, we can think
of the click event as a stream:

//HTML code
<button id='save'>Save</button>

//TS code
const saveElement = document.getElementById('save');
saveElement.addEventListener('click', processClick);
Exploring the pillars of reactive programming 5

function processClick(event) {
console.log('Hi');
}

As implemented in the preceding code snippet, in order to react to this click event, we
register an EventListener event. Then, every time a click occurs, the processClick
method is called to execute a side effect. In our case, we are just logging Hi in the console.
As you might have gathered, to be able to react when something happens and execute
a side effect, you should listen to the streams to become notified. We can say listen or
observe to get closer to the reactive terminology. And this leads us to the observer design
pattern, which is at the heart of reactive programming.

Observer patterns
The observer pattern is based on two main roles: a publisher and a subscriber.
A publisher maintains a list of subscribers and notifies them or propagates a change every
time there is an update. On the other hand, a subscriber performs an update or executes a
side effect every time they receive a notification from the publisher:

Figure 1.1 – The observer pattern


So, to get notified about any updates, you need to subscribe to the publisher. A real-world
analogy would be a newsletter; you don't get any emails if you don't subscribe
to a newsletter.
6 The Power of the Reactive Paradigm

This leads us to the building blocks of RxJS. They include the following:

• Observables: These are a representation of the data streams that notify the
observers of any change.
• Observers: These are the consumers of the data streams emitted by observables.

RxJS combines the observer pattern with the iterator pattern and functional programming
to process and handle asynchronous events.
This was a reminder of the fundamentals of reactive programming. Remember, it is
crucial to understand when to put a reactive implementation in place and when to
avoid it.
In general, whenever you have to handle asynchronous tasks in your Angular application,
always think of RxJS. The main advantages of RxJS over other asynchronous APIs are
listed as follows:

• RxJS makes dealing with event-based programs, asynchronous data calls, and
callbacks an easy task.
• Observables guarantee consistency. They emit multiple values over time so that you
can consume continuous data streams.
• Observables are lazy; they are not executed until you subscribe to them. This helps
with writing declarative code that is clean, efficient, and easy to understand and
maintain.
• Observables can be canceled, completed, and retrieved at any moment. This makes
a lot of sense in many real-world scenarios.
• RxJS provides many operators with a functional style to manipulate collections and
optimize side effects.
• Observables push errors to the subscribers and provide a clean way to handle errors.
• RxJS allows you to write clean and efficient code to handle asynchronous data in
your application.

Now that we have given some insight into the reactive programming pillars and detailed
the major advantages of RxJS, let's shed some light on the relationship between Angular
and RxJS.
Using RxJS in Angular and its advantages 7

Using RxJS in Angular and its advantages


RxJS is a first-class citizen in Angular. It is part of the Angular ecosystem and is used in
many features to handle asynchronous operations. Primarily, this includes the following:

• HTTP client module


• Router module
• Reactive forms
• Event emitter
• Async pipe

We will discuss each of the following concepts in the subsequent subsections.

Note
We recommend taking a quick look at https://angular.io/docs.
Here, you can find further details about the features mentioned earlier.

The HTTP client module


You might be familiar with the HTTP client API provided by Angular in order to
communicate with your server over the HTTP protocol. The HttpClient service is
based on observables to manage all transactions. This means that the result of calling the
API methods (such as GET, PATCH, POST, or PUT) is an observable.
In the following code snippet, we have an example of an Angular service that injects
the HttpClient service and fetches data from the server using the HttpClient.
get() method:

Import { Injectable } from '@angular/core';


import { HttpClient } from '@angular/common/http';
import { Observable} from 'rxjs';
import { environment } from '@env/environment';
const BASE_PATH = environment.basePath;

@Injectable()
export class RecipesService {
constructor(private http: HttpClient) { }
getRecipes(): Observable<Recipe[]> {
return this.http.get<Recipe[]>(`${BASE_PATH}/recipes/search/
8 The Power of the Reactive Paradigm

all`);
}

The following is the content of the environment.ts file where we define the
basePath property of our backend:

export const environment = {


basePath: '/app/rest',
production: false
};

The getRecipes() method or, to be more accurate, the call to this.http.


get<Recipe>(`${BASE_PATH}/recipes/search`) returns an observable that
you should subscribe to in order to issue the GET request to the server. Please note that
this is an example of an HTTP transaction, and it is the same for all of the other HTTP
methods available in the API (such as POST, PUT, and PATCH)
For those familiar with promise-based HTTP APIs, you might be wondering, in this case,
what the advantages of using observables are.
Well, there are a lot of advantages but the most important ones are listed as follows:

• Observables are cancellable, so you can cancel the HTTP request whenever you
want by calling the unsubscribe method.
• Also, you can retry HTTP requests when an error occurs or an exception is thrown.
• The server's response cannot be mutated by observables, although this can be the
case when chaining then() to promises.

The router module


The router module, which is available in the @angular/router package, uses
observables in router events and activated routes.

Router events
The router exposes events as observables. The router events allow you to intercept the
navigation life cycle. The following list shows the sequence of router events:
• NavigationStart
• RouteConfigLoadStart
• RouteConfigLoadEnd
Using RxJS in Angular and its advantages 9

• RoutesRecognized
• GuardsCheckStart
• ChildActivationStart
• ActivationStart
• GuardsCheckEnd
• ResolveStart
• ResolveEnd
• ActivationEnd
• ChildActivationEnd
• NavigationEnd
• NavigationCancel
• NavigationError
• Scroll

Note
We recommend that you take a quick look at https://angular.io/
api/router/Event. Here, you can find further details about the events
and their order.

To intercept all the events that the router goes through, first, you should inject the
Router service, which provides navigation and URL manipulation capabilities. Then,
subscribe to the events observable available in the Router object, and filter the events
of the RouterEvent type using the rxjs filter operator.
This is an example of an Angular service that injects the Router object in the
constructor, subscribes to the router events, and just traces the event ID and path in the
console. However, note that you can also introduce pretty much any specific behavior:

import { Injectable } from '@angular/core';


import { Router, RouterEvent } from '@angular/router';
import { filter } from 'rxjs/operators';
@Injectable()
export class CustomRouteService {
constructor(public router: Router) {
this.router.events.pipe(
10 The Power of the Reactive Paradigm

filter(event => event instanceof RouterEvent)


).subscribe((event: RouterEvent) => {
console.log(`The current event is : ${event.id} |
event.url`);
});
}
}

You can filter any specific event by putting the target type. The following code example
only filters the NavigationStart event and traces the event ID and path inside the
console. However, you can also introduce pretty much any specific behavior:

import { Injectable } from '@angular/core';


import { NavigationStart, Router } from '@angular/router';
import { filter } from 'rxjs/operators';

@Injectable()
export class CustomRouteService {
constructor(public router: Router) {
this.router.events.pipe(
filter(event => event instanceof NavigationStart)
).subscribe((event: NavigationStart) => {
console.log(`The current event is : ${event.id} |
event.url`);
});

}
}

The majority of Angular applications have a routing mechanism. The router events change
frequently over time, and it makes sense to listen to changes to execute the side effects.
That's why observables are a flexible way in which to handle those streams.
Random documents with unrelated
content Scribd suggests to you:
Chapter Seven.
It was evening when we got back to the encampment. On
casting our eyes towards the ship, her appearance, as she
lay overlapped with masses of ice on her beam ends, could
not fail to produce a melancholy feeling.

“She’ll never float again!” exclaimed the captain with a sigh.


“We must make the best of things, however, as they are.”

The men had progressed with the house. It was already


habitable, though much more was to be done to enable us to
bear the piercing cold of an arctic winter.

Next day was employed in getting everything out of the ship,


which could be reached, likely to be useful, as she could no
longer afford us a safe shelter. We began to cut away the
bulwarks, the upper planks, and indeed all the wood we
could get at, to serve for fuel as well as to strengthen the
house. While thus employed, the fearful sounds from which
we had for some time been free, again assailed our ears.
There was a sudden movement of our floe, while all around
us, and especially to the northward, we could see the ice
heaving and tumbling, huge masses falling over, and floes
rising one above another. Should our floe be subject to the
same violent pressure, a slab might slide over it and sweep
us to destruction. Even should some of the more active
manage to climb to the top, our house and boats and stores
must inevitably be lost, and those who might have escaped
at first would, ere long, be frozen to death.

The hours we thus passed, not knowing at what moment the


catastrophe might occur, were terrible in the extreme. To
work was impossible. At length, however, the disturbance
ceased. The intense cold quickly congealed the broken
masses together, and we were able to turn in and sleep
soundly.

The next day all was quiet. The captain was of opinion that
we should move no further north, and that, should our floe
become detached, we might expect to drift to the
southward.

The captain’s observations showed that at present we were


stationary, but it was still doubtful whether our floe was or
was not united to the main body. The captain, Mr Patterson,
my brother, the boatswain and I, had been discussing the
subject one evening as we sat in the hut, and were
afterwards talking of the Aurora Borealis when I agreed to
go out and ascertain if any of peculiar brilliancy was visible.

On emerging from the hut, I gazed up at the sky. An Aurora


was blazing brilliantly, forming an irregular arch, from which
showers of rays of many colours spread in every direction. I
was watching it with intense admiration, and was intending
to go back and call my companions, when one of the dogs
which had followed me gave a loud bark. It was answered by
a growl. Looking over the ice I saw two enormous shaggy
monsters, who, sniffing the air, advanced cautiously towards
me. The brave dog dashed forward. In vain I called him to
return.

Satisfied that our visitors were Polar bears which must have
come from the main land, I hurried back, closing the door
behind me to prevent them from entering. The captain,
mate, and my brother seized their rifles, as I did mine,
hoping to kill one or both of the intruders. As we opened the
door, a loud cry uttered by a dog reached our ears. One of
the bears had seized the animal and was carrying him off,
satisfied with his prize. The other was creeping on towards
the hut. Our bullets quickly settled him, and he rolled over.
We then gave chase to the other who was carrying off the
dog, but we were compelled to stop and reload, and by the
time we had done this, so rapidly did the animal run that he
was far beyond our reach, and all hope of rescuing our
canine companion was over. We regretted the loss of the
brave dog. It was a lesson to us not to let the others loose
until we were ready to assist in attacking any similar
visitors. The bear was quickly skinned and cut up. The skin
would serve us for clothing, the fat for fuel, the meat for
food. This visit of the bears showed us that the field of which
our floe formed part must be attached to the land-ice. Our
captain being anxious to visit the shore, intending, should a
favourable spot be found, to form our winter quarters on it—
we agreed to set out the next morning.

Much to our disappointment, when the time came, the


captain was unable to go. He was very unwell, and my
brother forbade him to take the journey. As he did not
improve, Andrew was unable to leave him, and it was finally
settled that the mate, Sandy, Ewen, Croil, another man, and
I should form the party to proceed to the land. We had a
small sledge which had been manufactured some time
before. To this we attached our remaining dogs, and loaded
it with stores of ammunition and provisions, including food
for the dogs. Each of us carried also a small load as well as
our rifles and long poles to assist our progress. Our
companions cheered us as we set off, several accompanying
us part of the way from the camp. We were by this time
pretty well accustomed to travelling over the ice, but we had
great difficulty in making our dogs, who had not been well
trained, pull together, and the mate, losing patience,
declared that he would rather drag the sledge himself, and
that he wished the dogs back again.
“If he were to try it for half an hour he would change his
tone,” observed Sandy to me; “the doggies will get along
well enough in a few days.”

“In a few days!” I exclaimed, “I thought that we should get


to the shore by nightfall.”

“Many a night will fall before we reach it,” answered Sandy.


“If we could go in a straight line over smooth ice, at a jog
trot, the case would be different. We shall have to make our
way in and out among the bergs and hummocks, and maybe
to take a long circumbendibus to avoid any waterholes in our
course; we are very likely to fall in with some, solid as the
ice appears hereabouts.”

I soon found that Sandy was perfectly correct in his


prognostications. For the early part of the first day we got on
well enough. We had our choice of climbing over numerous
ridges from ten to twenty feet in height, or going round until
we could find a passage between them. We had thus made
less than three miles when the night closed in on us. We
then put up our tent, lighted our lamp, and crept into our
sleeping sacks. Though our quarters were rather close, we
were more comfortable than I could have supposed possible.
We had a long night, and with the first streaks of dawn,
having breakfasted inside our tent on coffee boiled over the
lamp, we again proceeded. Our dogs, I should have said,
slept outside, and they formed a sufficient guard to give us
notice should any bears approach.

The next day we made even less progress than on the first,
though we met with no accident to hinder us. Sometimes we
dragged the sledge over the hummocks, and sometimes we
went round them, the dogs preferring the former method, as
while we toiled they sat up on their tails watching our
proceedings with infinite satisfaction.

The next night I was awakened by hearing a rustling sound,


which I guessed was snow falling, but I soon dropped asleep
again forgetting all about it. In the morning I saw that the
sides of the tent were considerably pressed in, and on
drawing aside the curtain which closed the front, a mass of
snow fell inside. Looking out, what was our dismay to find
that we were entirely surrounded. Travelling which was
before difficult would now be doubly so. However, on further
examination we found that, having chosen a sheltered spot
under a hummock, the snow had drifted round us.

We easily, therefore, forced our way out, roused up the half-


buried dogs, whose noses showed their whereabouts, and
having taken our morning meal doubled up our tent and
then trudged forward, Sandy leading. We followed in line,
thus making a path for the dogs who without difficulty kept
up with us. Before long we came to a berg from which
extended north and south a line of hummocks. It seemed to
bar further progress. To ascertain which course to pursue,
we agreed to climb to the top of the berg, leaving Ewen and
Croil to take charge of the sledge. The mate, Sandy, and I,
at once commenced the ascent. It was no easy work, and we
ran great risk of slipping down again and breaking our limbs.
Still, by persevering, the top at length was gained. We could
see the land very clearly to the westward, and between it
and us the ice appeared far more level than any we had
hitherto passed over. To the north it was utterly
impracticable. To the southward we discovered a passage
which we hoped to reach in the course of the day. The
mate’s belief was that we were close upon the land-ice, and
that by pushing on we could reach it by nightfall.

Having made these observations we prepared to descend,


but we found that the chance of falling when doing so would
be far greater than when ascending. It appeared, however,
from where we stood, that there was a slope on the
southern side where we might get down with comparative
ease. There was, however, a projecting ledge which must be
knocked away before we could reach the slope. We had
brought ropes with us, and Sandy passing one round his
waist, begged the mate and me to hold it at the other end
while he advanced with his staff at the point of which he had
secured a huge lump of ice. Using this us a sledge hammer,
he began knocking away at the ledge, and after a few blows
the whole mass giving way went thundering down the slope.

“It’s just as well to clear that off,” he observed, “or it might


have come down on our heads.”

This was the more likely when he told us that he had


observed a deep crack, which had induced him to make the
attempt to knock the ledge away.

We now descended and rejoined Ewen and his companions,


who had been greatly alarmed at seeing the mass of ice
come rattling down, supposing that some accident had
happened to us, while they had with difficulty restrained the
dogs from galloping away from them.

We now directed our course southward, and were not


disappointed in finding a passage through the hummocks,
which enabled us to get on the smoother land-ice. We had,
however, soon to camp. To render our tent warm, having
cleared away the snow, we built a wall round it which
sheltered us from the wind.

On the evening of the second day after this, we reached the


shore, which rose bleak and barren before us. Yet it was a
satisfaction to set our feet on firm ground. We landed in a
small bay, the shore for a short distance shelving up to the
foot of the cliffs, which—as they extended round to the east
—would, we agreed, afford us shelter from the more bitter
blasts of winter. The rocks were bare and rugged. Here and
there a few lichens appeared, which to our eyes, long
unaccustomed to anything of a green tint, seemed very
pleasant.

“This will do!” cried the mate, “if our shipmates can reach
this, we may pass the winter far better than we should have
done on the open floe.”

As we had but a few more minutes of daylight, we hurriedly


pitched our tent on a level spot close under the rocks, piling
up the snow around it as before.

The mate was anxious to return at once with the news of our
success, and to guide the party to the shore. He hoped, with
a good night’s rest, to be able to set off early in the
morning, and to perform a great part of the distance before
nightfall.

Sandy suggested, that it would be as well if some of us


remained, as it would be necessary to carry but few articles
on the sledge, and the dogs would the more easily perform
the journey. He offered to go with Ewen and Croil, but to this
the mate would not agree, and announced his intention to
set off with Croil, leaving the rest of us to build a snow-hut
for the reception of the party.

We had brought, I should have said, a couple of lamps with


sufficient oil. We were therefore provided with one of the
chief necessaries of life. We hoped also to shoot a bear, or
perhaps some birds, to increase our stock of provisions.

When morning returned, however, a storm was blowing


outside the bay, though within we were tolerably sheltered
from its fury. To have attempted to cross the ice while it
continued would have been madness.

The mate and Sandy therefore assisted us in putting up a


hut. We had abundance of snow from a drift collected on the
opposite side of the bay, though we soon exhausted that
which lay immediately round us. The storm, however,
increased to such an extent that we were compelled to take
shelter within our tent, which, had it not been surrounded by
a snow wall, would inevitably have been blown down. As we
sat crowded together in our tent, waiting for the cessation of
the storm, the howling and roaring of the wind among the
rocks in no way served to raise our spirits, but rather
increased the gloomy forebodings of evil which stole over us.

The mate announced his intention of taking a look round, to


see what prospect there was of the weather clearing.

“Stay here, lads,” he said, taking up his gun, “there’s no


reason why you should be exposed to the cold. I’m more
accustomed to it than you are.”

“Not more than me, sir,” said Sandy; “I’ll go with you, if you
like.”

“No, no, boatswain. You stay and look after the others. You
are older than I am, at all events, and require more rest.”

Saying this the mate went out and closed the door of the
tent.

Ewen, Croil, and the seaman were asleep. Sandy and I


talked on for some time.

“Wonder the mate doesn’t come back,” said the boatswain.


“I’m afraid something has happened to him. He can’t have
lost his way on the ice, but he may have slipped over a rock,
or into a seal hole, if any are to be found close in shore.”

We waited a little longer, and at length Sandy, starting up,


exclaimed, “We must go and look for him.”
Just then our ears were saluted by a loud roar, which made
the rest of the party jump up. We all hastened out. No one
was to be seen.

“Where did the sound come from?” asked Sandy. “I thought


it was quite near.”

“From the other side of the rock,” I answered.

We hastened towards the spot, in the direction to which I


pointed. We all had our guns in our hands ready for an
encounter with a bear, which we expected to see. What was
my horror on getting round the rock to discover the mate on
the ground, a huge shaggy monster standing over him. We
crept on, afraid, should we shout, that the bear might carry
off his victim. Whether the mate was dead or alive, we could
not tell, but he lay perfectly still. Sandy was leading, but he
was not a first-rate shot, and I would rather have trusted to
my own rifle. At last the bear made a movement, and Sandy,
thinking he was going to bite the mate, fired, but he only
wounded the animal in the back. What was my horror to see
it seize the mate by the body and scamper off with him. We
all fired, but dared not aim at the animal’s head, believing
that the mate was still alive, for fear of killing him. I stopped
to reload, as did Ewen.

“After him, lads,” shouted Sandy, but the bear was far too
fleet for us to overtake, and to our grief and dismay
disappeared with his victim behind the rocks to the
northward.

We searched in vain for our companion. Though we traced


the way the bear had gone by the crimson stains on the
white snow, it convinced us that the poor mate was killed. To
follow further would have been useless. With sad hearts we
returned to our tent, almost frozen by the cold blast, to
spend the most melancholy night we had yet passed.
We had now to settle on our future proceedings. Sandy had
become the leader of the party. He proposed returning to
the ship, but none of us wished to be left behind, and
preferred rather to undergo the toils and risks of the journey
than to remain on shore. But of this Sandy would not hear.
He declared that he could go very well with only one of us,
and that the other three by remaining—I acting as officer—
could manage well enough by ourselves.

At last I gave in, and Sandy with the seaman set off as soon
as the wind had abated. We watched them as they made
their way over the plain of ice, their forms diminishing into
mere dots, then finally disappearing. We in the meantime
were working away to complete our hut and to render it as
habitable as possible. The flesh of the bear we had killed
afforded us an ample supply of food, while the fat served to
increase our stock of fuel. There was probably drift-wood on
the shore, but except a few pieces which stuck up above the
snow, we could obtain none. We took care of every scrap we
could find, not to burn, but to manufacture into such articles
as we might require. In the crevices of the rocks we
discovered some low creeping plants which in any other
region would have been bushes, but were here a mere
collection of twigs, no thicker than our little fingers, just
appearing above the ground. We agreed that each should
take certain duties, and it was settled that Croil should stay
at home and look after the hut, employing himself in either
cooking or scraping the bear’s skin to make it fit for use as a
covering. Should we kill a sufficient number of bears, we
intended to fasten the skins of some of them together so as
to form a roof to our hut, while others would make great-
coats or bed coverings.

Soon after Sandy and his companion had departed, Ewen


and I took our guns both for the sake of exercise and to try
and shoot bears, reindeers, or musk-oxen which we thought
it possible might be found in that region. We were not aware
that the latter animals had migrated southward by that time,
or indeed that they were likely to be found only on level
ground where the depth of the snow was not sufficient to
prevent them from getting at the moss or lichens beneath. I
was thankful to have Ewen as my companion. He had greatly
improved since he came on board and showed that he
possessed qualities which I did not before suspect, so that I
felt for him as I should for a brother. The atmosphere had
become calm and comparatively warm though the snow
remained hard and crisp.

Ewen and I kept under the cliffs and were tempted to make
our way much further south than we had hitherto gone, in
the hopes of discovering some opening into the interior of
the country. We at last reached a part of the cliffs where,
though very rugged, they were less precipitous than in other
parts. The sun was sinking behind them, but we still had
abundance of daylight for exploring. Ewen offered to climb
to the top in the hopes of obtaining an extensive view and
perhaps of finding level ground where we should have the
chance of finding deer or oxen. There was no reason why we
should both run the risk, for a risk there was, though a slight
one.

“Let me make the attempt alone, while you remain below,


and point out to me the best path to take,” he said.

I did not much like to do this, but he declared that if I


insisted on going he would give up the expedition. As I saw
the sense of his proposal, I consented, and he commenced
climbing up, rifle in hand. He had gone some distance when
I saw a creature creeping along the rocks above his head,
and directly afterwards, as it came more into sight, I saw
that it was a huge bear. I shouted to him, to draw his
attention to it, should he not have discovered the animal. He
stopped and began to descend to a position from whence he
could take a steady aim at the monster, should it come
within his reach. What was my horror directly afterwards to
see two other bears crawling out from among the rocks by
which they had hitherto been concealed, evidently having
discovered him. It seemed impossible that he should escape.
I shouted to him, when he again began clambering up the
rock. To my dismay, as he did so the first bear crawled down
and seated itself on a point so as to intercept him.

The two other creatures got closer and closer with the
evident intention of seizing him. I trembled for his safety,
and hurried to the nearest spot from which I could take a
steady aim.

“Never mind the fellow above you,” I shouted. “If you will
shoot the ere nearest to you, I will manage the other, and
we will then tackle the third if he attempts to come down.”
I could well enter into Ewen’s feelings. It was surprising, in
the perilous position in which he was placed, that he should
have retained any presence of mind.

Following my advice, he sat himself down on the rock and


took aim, waiting until I should fire.

“Now!” I cried, and we both pulled our triggers at the same


moment.

I own that I trembled lest either one or both of us might


miss, in which case it seemed impossible that he should
escape destruction. As the smoke cleared away from before
my eyes, I saw the bears in motion, but instead of
advancing they both fell back and came tumbling down the
cliff close to where I was standing. I rapidly loaded, as did
Ewen. We had still another antagonist to contend with,
whom he must tackle alone, for I could not help him.

Just as I expected to see the bear crawling down the rocks


to seize my friend, to my infinite satisfaction, the creature,
alarmed by the reports, turned tail and began clambering up
the cliff.

I shouted to Ewen not to shoot, as, should he only wound


the bear, it might in its rage turn and attack him. I also had
to look after one of the others, who though wounded, was
not dead, and recovering from its fall, was looking about
apparently for the foe who had injured it. On espying me it
began to advance, growling furiously. As blood was flowing
from behind its shoulder, I hoped that it might soon drop,
but in the meantime it might tear me to pieces, and perhaps
treat Ewen in the same way. To run from a bear is at all
times very dangerous, unless to gain protection of some sort
at no great distance; for the bear—clumsy as it looks—can
run much faster than a man. I, therefore, having reloaded
my rifle, stood with it ready to send a shot through the
animal’s head. I waited until the wounded bear was almost
close upon me, and I could not refrain from uttering a shout
of satisfaction as it rolled over perfectly dead. Ewen in the
meantime, approaching the other, had finished it by firing a
bullet through its head.

“I wish that we had the sledge to take home the meat and
skins,” observed Ewen, “but we must carry as much as we
can.”

Our fear was that, should we leave the meat, other bears, of
whom there appeared to be a whole colony in the
neighbourhood, would come and devour it. We managed to
get off the skins, which were likely to prove most valuable to
us; and, loaded with them and a portion of the meat, we
returned to the hut, where we found Croil anxiously looking
out for us. He too, had seen a couple of bears moving across
the bay, and was afraid that we might have been attacked
by them, and suffered the fate of the poor mate.
Chapter Eight.
We now waited in anxious expectation for the arrival of our
shipmates, but they did not appear. The days were getting
shorter, the nights longer. The cold was increasing. Often
and often we gazed out over the ice. As far as we could
judge no change had taken place in it. A vast snow-covered
plain, with here and there mountainous heights of ice could
be seen extending as far as the horizon. Unfortunately we
had not brought a telescope, or we thought that we might
have discovered our friends. At length we began to entertain
the most serious apprehensions as to their fate.

We had one evening turned in, and, having closed the door
of the hut, had lighted our lamp and composed ourselves to
sleep, when Ewen roused me up.

“I heard a shout!” he exclaimed, “they must be coming.”

We slipped into our day clothing, and hurried out, carrying


our rifles in our hands, for we never moved without them.

Again there was a shout: we replied to it with all our might.


Some one was evidently approaching. More clearly to show
our position, I fired off my rifle, and sent Croil in to light a
small piece of drift-wood the only thing we possessed to
serve as a torch. Again and again we shouted: at length we
caught sight through the gloom of night of some dark spots
moving over the snow.

“Hurrah!” cried Ewen, “there are our shipmates!” Soon after


he had spoken I discovered three of the dogs dragging the
sledge and two men following them. The one was Sandy, the
other Hans the seaman.
Hurrying forward we led them up to the hut. Sandy could
scarcely speak.

“We are well-nigh starved, and I thought we should never


get back,” he said at length.

“Where are our shipmates? Why haven’t they come?” I


asked.

“I’ll tell you all about it when we have had some food and
rest. Can you give us something to eat?”

“Plenty,” I answered, leading him and Hans into the hut,


while Ewen and Croil unharnessed the poor dogs, who
looked well-nigh famished. Ewen gave them some bears’
flesh, and they devoured it with a greediness which showed
that they had gone long without a meal.

We soon had some slices of meat frying on our stove and


some snow melting. After the two weary travellers had
eaten, and drank some hot coffee, Sandy gave us the
alarming intelligence that he had been unable to reach the
camp. On arriving at the edge of the land-ice, what was his
dismay to discover a wide gap between it and the field in the
midst of which our friends were encamped, and which was in
motion drifting southward. Still, hoping that it might again
come in contact with the land-ice, he determined to move in
the same direction. He caught sight indeed of a flag and
what he took to be a portion of the wreck, though at so
great a distance that he did not suppose the sound of his
rifle, which he fired off, would be heard. No object indeed
would have been gained had it been so, as it would have
been impossible for one party to communicate with the
other. For two days he followed the floe, but the distance
between it and the land-ice increased. At length the ice over
which he was travelling became so rough that he could
proceed no further; he lost sight of the floe and its living
freight, and was reluctantly compelled to return for want of
food. One of the dogs gave in and it was killed and eaten.
The last morsels had been consumed the day before he and
Hans reached the hut. Their joy at finding us still there may
be imagined, for had we by any chance fallen in with natives
and accompanied them to the south, they fully expected to
perish.

As soon as the meal was over, the two weary travellers lay
down to sleep. Croil imitated their example, while Ewen and
I sat up by the light of the lamp, I mending clothes and my
friend engaged in preparing a small tub for holding bear’s
grease to serve us for fuel. Our conversation naturally took a
melancholy turn. The thought that the floe on which were
my brother and his companions might be dashed to pieces,
and that they would perish miserably, was painful in the
extreme. We thought more of them, indeed, than of
ourselves, though our position was truly perilous. Our only
shelter during the intense cold of an Arctic winter was an ice
hut. Hitherto the bears we had shot had afforded us food
and fuel; but they might take their departure, and we should
then have no other food on which to depend, until the return
of spring should enable us to kill walruses and seals. No
ships, even in the summer, were likely to penetrate so far
north, for few whalers had got so near the pole as the Hardy
Norseman had done, and destruction had overtaken her.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

textbookfull.com

You might also like