Professional Documents
Culture Documents
First examples
content_copyopen_in_newdocument.addEventListener('click', ()
=> console.log('Clicked!'));
Purity
What makes RxJS powerful is its ability to produce values using pure
functions. That means your code is less prone to errors.
content_copyopen_in_newlet count = 0;
fromEvent(document, 'click')
The scan operator works just like reduce for arrays. It takes a value
which is exposed to a callback. The returned value of the callback will
then become the next value exposed the next time the callback runs.
Flow
RxJS has a whole range of operators that helps you control how the
events flow through your observables.
This is how you would allow at most one click per second, with plain
JavaScript:
content_copyopen_in_newlet count = 0;
document.addEventListener('click', () => {
if (Date.now() - lastClick >= rate) {
lastClick = Date.now();
});
With RxJS:
fromEvent(document, 'click')
.pipe(
throttleTime(1000),
Values
Here's how you can add the current mouse x position for every click, in
plain JavaScript:
content_copyopen_in_newlet count = 0;
console.log(count);
lastClick = Date.now();
});
With RxJS:
fromEvent(document, 'click')
.pipe(
throttleTime(1000),
If you're scratching your head, don't worry. I think most people would be confused by that
statement alone. Luckily for us, the manual gives an even better definition:
An Operator is a function which creates a new Observable based on the current Observable.
This is a pure operation: the previous Observable stays unmodified.
Now let's take a look at 6 basic Operators: of, from, map, tap, switchMap, take.
Also, unlike of, it will emit each element in an Array or Iterable in sequence, rather than the
full value. Once all elements of the Array or Iterable have been emitted, a completion
notification is sent to any subscribers.
Let's take the example we used for of to see this difference in action:
const arr = [1, 2, 3];
Emitted Values: 1
Emitted Values: 2
Emitted Values: 3
As we can see by the multiple logs, the from Operator took each number and emitted it as a
value. The subscriber received each value in sequence, and called console.log three
times.
We can also use a value such as a string:
Emitted Values: H
Emitted Values: e
Emitted Values: l
Emitted Values: l
Emitted Values: o
How about for a Promise? Let's take a look!
fromArr$
.pipe(map((value) => value + 10))
.subscribe((value) => console.log(`Emitted Values: `, value));
You'll notice the introduction of the .pipe() call. This is RxJS's method for applying
operators to an Observable's stream before you subscribe to it. It will pipe the value emitted
from the Observable through each operator passed as an argument, before passing the final
transformed value to the subscribe method. We'll cover this in more detail in a future
article!
In this example, as map is a transformation Operator, it must be used within the .pipe() call
so that it can transform the value it receives from the Observable. We are simply adding 10
to the value, and emitting the transformed value.
You can see this in the output:
Emitted Values: 11
Emitted Values: 12
Emitted Values: 13
We can do almost anything in the map Operator, but a common use-case would be to get a
property from an object that is emitted in an Observable stream. We can use our Promise
example to see this in action:
const examplePromise = new Promise((resolve, reject) => {
// Do some async code and resolve and object with an id property
return resolve({ id: 1 });
});
fromArr$
.pipe(tap((value) => console.log("Received value: ", value)))
.subscribe((value) => console.log(`Emitted Values: `, value));
Which would output:
Received value: 1
Emitted Values: 1
Received value: 2
Emitted Values: 2
Received value: 3
Emitted Values: 3
fromArr$
.pipe(take(1))
.subscribe((value) => console.log(`Emitted Values: `, value));
From the output below we can see we only received and used 1 value from the array:
Emitted Values: 1
It can be used in situations where we want to limit how many user-produced events
(fromEvent) we want to handle, for example, the first time the user clicks in our app
What is RxJS ?
It's an acronym for Reactive Extensions of JavaScript. and it's a JavaScript library for
handling Asynchronous data streams and events.
What is Stream ?
It's an algorithm that does not allow threads competing for the same resource to be
indefinitely postponed through mutual exclusion of the resource.
What is an Obserable?
Promise:
Observable:
Hot Observables emit values even before the subscription is made. Used when
sharing data among many subscribers.
These are methods that can be applied to the observable in order to modify the data
stream.
Observers: They are the listeners/ consumers of the data stream; Observers listen
/subscribe to the data stream.
What is Subject ?
Replay Subject: - All observers will revive data prior to their subscription; uses a
buffer to hold values and re-emits values on new subscriptions.
A scheduler controls the execution of when the subscription has to start and be notified.
RxJS Map: It's a flattening operator used to transform current emitted data values to
the desired data format.
http$
.pipe(
tap(() => console.log('HTTP request executed')),
map(res => Object.values(res['payload']))
)
.subscribe(
books => console.log("books", books)
);
Higher-Order Mapping: These are Rxjs operators used to map source observable
values into other observables.
Used to combine multiple HTTP requests; alleviating the need for nested subscribers.
All HTTP requests are sent to the backend sequentially; Once the previous request
has been completed.
this.form.valueChanges
.pipe(
concatMap(formValue => this.http.put("/api/book/",formValue))
)
.subscribe(
response => ... handle successful ...,
err => ... handle error ...
);
ii) What is RxJS mergeMap?
this.form.valueChanges
.pipe(
mergeMap(formValue =>
this.http.put("/api/book/", formValue))
)
.subscribe(
res => ... handle successful response ...,
err => ... handle error ...
);
iii) What is RxJS switchMap?
switchMap: An operator that combines source values into an output observable that
represents the most recent projected observable.
When you want to get the most rescent updated values the second source
anticipated to delay.
UseCase:
a) Update data from local cache or CDN before retrieving from backend.
It behaves like mergeAll. However, exhaust ignores every new inner Observable if the
previous Observable has not yet completed. Once that one completes, it will accept
and flatten the next inner Observable and repeat this process.
ExhaustMap: Projects each source value to an Observable which is merged in the
output Observable only if the previous projected Observable has completed.
// outputs
// { age: 27, name: 'Foo', isDev: true }
// { age: 25, name: 'Bar', isDev: true }
// { age: 29, name: 'Beer', isDev: false }
Redux
What is Redux?
Open-Source JavaScript library for managing application state. Used in frontend framework
such as React, Angular & Rxjs
-Single source of Truth: All application data is stored in a single object tree.
A4. An Observable in RxJS is a core primitive representing a lazy, push-based collection that
can emit multiple values over time. It serves as a blueprint for creating and managing data
streams, allowing developers to handle asynchronous operations more effectively.
Observables are lazy by nature, meaning they do not start emitting values until a subscriber
actively listens for them. An Observable can emit three types of values: onNext (data),
onError (error), and onCompleted (completion).
Q6. What are the key differences between Observables and Promises?
A6. Observables and Promises are both used for handling asynchronous operations, but they
have some key differences:
Observables Promises
Can emit multiple values over time Emit a single value
Lazy and only execute when subscribed Eagerly execute upon creation
Can be canceled via unsubscription Cannot be canceled
Support various transformation methods Limited transformation capabilities
A7. To create an Observable in RxJS, you can use the Observable class and the create()
method. Inside the create() method, you define the logic for emitting values, handling errors,
and notifying subscribers of completion. Here's an example:
A8. To subscribe to an Observable in Angular, you use the subscribe() method, providing
callbacks for handling data, errors, and completion. Here's an example:
A9. To unsubscribe from an Observable, you can call the unsubscribe() method on the
subscription object returned by the subscribe() method. This is important to prevent memory
leaks, especially when working with long-lived subscriptions. Example:
A10. RxJS operators are functions that allow developers to manipulate and transform
Observable streams. They can be used for tasks like filtering, mapping, combining, and error
handling. Operators are categorized as creation, transformation, filtering, combination,
multicasting, error handling, and utility operators.
Q11. What is the purpose of the pipe() function in RxJS?
A11. The pipe() function in RxJS is used to chain multiple operators together, allowing you to
apply a series of transformations to an Observable stream. The pipe() function takes one or
more operator functions as arguments and returns a new Observable with the applied
transformations.
Q12. Can you provide some examples of commonly used RxJS operators in Angular
applications?
A12 (Continued). Some commonly used RxJS operators in Angular applications include:
A13. In RxJS, you handle errors using the catchError operator, which intercepts errors emitted
by an Observable and allows you to handle or recover from them. You can provide a function
that either returns a new Observable or throws an error. Here's an example:
Q14. How can you implement a retry mechanism for failed HTTP requests in Angular using
RxJS?
A14. You can implement a retry mechanism for failed HTTP requests in Angular using the
retry or retryWhen operators from RxJS. The retry operator automatically resubscribes to the
source Observable a specified number of times when an error occurs. The retryWhen
operator allows you to define more complex retry strategies based on custom logic. Here's
an example using the retry operator:
A15. A Subject in RxJS is a special type of Observable that also acts as an Observer. It can
both emit values and subscribe to other Observables. Subjects can multicast values to
multiple subscribers, making them useful for scenarios where you need to share a single data
stream with multiple consumers. Subjects can also be used for implementing event buses or
broadcasting data to different parts of your application.
Q16. How do Subjects differ from Observables?
1. Subjects can act as both Observables and Observers, while Observables can only emit
values.
2. Subjects can multicast, meaning they can emit values to multiple subscribers
simultaneously, while Observables are unicast by default.
1. Subject: The basic Subject, which can multicast and act as both an Observable and
Observer.
2. BehaviorSubject: A variant of Subject that stores the latest value it has emitted, and it
will provide this value to new subscribers immediately upon subscription.
3. ReplaySubject: A variant of Subject that records a specified number of emitted values
and provides them to new subscribers upon subscription.
4. AsyncSubject: A variant of Subject that emits only the last value and only when the
source Observable completes. It is useful for caching results of HTTP requests or
other asynchronous operations.
F. Higher-order Observables
Higher-order Observables are useful when dealing with nested asynchronous operations
such as making multiple HTTP requests in sequence or handling multiple events in a specific
order. They allow you to chain and combine Observables, creating more complex data
streams.
To work with higher-order Observables, RxJS provides several operators such as mergeMap,
switchMap, and concatMap. These operators help to flatten and merge the nested
Observables into a single Observable stream that can be easily subscribed to.
In this example, the fetchData method fetches data from an API that returns a URL for
additional child data. The switchMap operator is used to switch from the parent data
Observable to the child data Observable, effectively flattening the higher-order Observable.
A20. The purpose of the switchMap() operator is to map each value emitted by a source
Observable to an inner Observable and switch to the latest emitted inner Observable,
canceling any previous subscriptions. It is useful when you want to switch between
Observables based on the latest emitted value and ensure that only one inner Observable is
active at any time. This helps prevent race conditions and unnecessary processing in cases
where the source Observable emits values rapidly.
For example, the switchMap() operator is commonly used in Angular applications for
handling search input, where you want to perform an HTTP request for the latest search term
while canceling any previous in-progress requests:
In this category of interview questions, candidates are evaluated based on their knowledge
of best practices and performance optimization techniques when using Angular and RxJS
together. These questions may cover topics such as memory management, error handling,
optimization of data streams, and efficient use of RxJS operators. Candidates should be able
to demonstrate their understanding of the importance of adhering to best practices and
optimizing performance in Angular applications using RxJS, as well as provide examples of
how they have applied these principles in their work.
Q21. How can you prevent memory leaks when using Observables in Angular?
A21. To prevent memory leaks when using Observables in Angular, you need to unsubscribe
from the Observable when the component is destroyed. There are several ways to achieve
this:
1. Manual unsubscribing: You can store the subscription and unsubscribe in the
ngOnDestroy lifecycle hook.
1. Using takeUntil operator: You can use the takeUntil operator along with a Subject
that emits a value when the component is destroyed.
import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; // ... private
destroy$ = new Subject<void>(); ngOnInit()
{ this.observable.pipe( takeUntil(this.destroy$) ).subscribe(value =>
console.log(value)); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); }
1. Using the async pipe: When using the async pipe in your templates, Angular
automatically handles the subscription and unsubscription.
A22. You can use the share() or shareReplay() operators to share a single Observable among
multiple subscribers. The share() operator creates a multicast Observable that shares a single
subscription to the source Observable. The shareReplay() operator does the same but also
replays a specified number of emitted values to new subscribers.
Q23. What are some best practices for error handling in RxJS?
1. Use the catchError operator to handle errors within the Observable pipeline.
2. When handling errors, consider providing a fallback value, returning a new
Observable, or rethrowing the error.
3. Use the retry or retryWhen operators to retry failed operations.
4. Make sure to handle errors in the subscribe method's error callback as a last resort.
Q24. How can you recover from errors and continue processing in RxJS?
A24. To recover from errors and continue processing in RxJS, you can use the catchError
operator, which allows you to handle errors within the Observable pipeline and continue with
a new Observable or a fallback value.
Q26. What are some performance pitfalls to avoid when using RxJS in Angular?
A 26. RxJS is a powerful library that is widely used in Angular for reactive programming.
However, it is important to be aware of some performance pitfalls that can affect the
performance of your Angular application. Here are some common performance pitfalls to
avoid when using RxJS in Angular:
1. Overusing the async pipe: While the async pipe is a convenient way to subscribe to
an observable in your template, it can lead to performance issues if you overuse it.
Each use of the async pipe creates a new subscription, which can add up if you have a
large number of components using it. To avoid this, consider subscribing to the
observable in your component instead and using the takeUntil operator to
unsubscribe when the component is destroyed.
2. Using unnecessary operators: RxJS has a large number of operators, and it can be
tempting to use them all. However, each operator adds overhead, so it's important to
use only the operators you need. Be mindful of which operators you are using and
consider whether they are really necessary.
3. Creating too many observables: Creating too many observables can also impact
performance. If you have multiple observables that emit the same data, consider
using the share operator to share the subscription and avoid creating unnecessary
observables.
4. Not using the unsubscribe method: When you subscribe to an observable, you need
to unsubscribe when you are done to avoid memory leaks. If you don't unsubscribe,
the subscription will stay active even after the component is destroyed, which can
lead to performance issues. To avoid this, always unsubscribe when you are done
with the subscription.
5. Using ngZone.run unnecessarily: The ngZone.run method is used to run code outside
of Angular's zone. While this can be useful in some cases, it can also impact
performance if used unnecessarily. Be mindful of when you are using ngZone.run and
consider whether it is really necessary.
To understand core concept of RxJS Map and different merge strategy click here
concatMap : Projects each source value to an Observable which is merged in the output
Observable, in a serialized fashion waiting for each one to complete before merging the next
- Official RxJS Docs
switchMap : Simply put, it means switching to a new observable. The previous inner
observable (result of the function you provided) is canceled for each emission and the new
observable is subscribed.
Q: What is NgRx?
Ans:
NgRx stands for Angular Reactive Extensions, NgRx Store provides reactive state
management for Angular apps inspired by Redux. NgRx has libraries for managing both global
and local state. Isolation of side effects in order to achieve a more streamlined component
architecture. Developer tooling that makes it easier for developers to construct a variety of
applications.
Refer for more questions on NgRX Interview Questions
zip and combineLatest are functions and withLatestFrom is operator that allows to combine
a few observable sequences in a different ways, that are really helpful in real world
application.
Composing functions and operators usually accept observables as their params and also they
return observable that emits array with values produced by argument observables. This result
observable emission logic is different depending on which operator or function we use
To understand RxJS more about Zip and combineLatest and withLatestFrom, click here
Q: What is Angular?
Ans:
It's a frontend framework, which was developed to build a single page application (SPA).
Click here to understand more about Angular.
Q: How to build full stack web application?
Ans:
Angular is extremely famous for modern web application development, Spring Boot and
Angular are a strong and developer-friendly combination if you want to create the full stack
web application.
We can use Spring Boot JWT with Angular for token authentication in web application.
To know more about Angular Spring Boot JWT Example click here
The lastest version of Angular framework is Angular 9 which is in pipeline to release in this
month.
Here are few differences between Angular and AngularJS are stated as follows
AngularJS supports the MVC design model. Angular relies on components and
directives instead.
Angular supports a hierarchical Dependency Injection with unidirectional tree-based
change detection. AngularJS doesn’t support DI
In AngularJS, a specific ng directive is required for the image or property and an
event. Angular, on the other hand, use () and [] for blinding an event and
accomplishing property binding, respectively
AngularJS doesn’t have mobile support while Angular does have
While JavaScript is the recommended language for AngularJS, TypeScript is the
recommended language for Angular
Q: What is Angular Material?
Ans:
It is a UI component library. Angular Material helps in creating attractive, consistent, and fully
functional web pages as well as web applications. It does so while following modern web
design principles, including browser portability and graceful degradation.
Angular 8 has been official release in May 2019, new features in Angular 8 are limited, but
there are still there are a lot of interesting things happening, we have much awaited Ivy
compiler as an opt-in feature, ng deploy is officially support by CLI and many more.
In the newest version of Angular 8, it has updated the core dependencies which
include tools like RxJS and TypeScript to v3
Another much awaited feature, the new rendering engine, and Bazel, the new build
system, which make possibility to build your CLI application more quickly. An opt-in
preview of the two should be available shortly
The improvements that have been made to Angular CLI bundling to eliminates the
need to put the web workers in a separate file
Lazy-loaded routes now use the standard dynamic import syntax instead of a custom
string. This means that TypeScript and linters will be strict checking when modules
are missing or misspelled. lazy-loaded import that looked like this:
The CLI continues to improve, and the ng build, ng test and ng run are now designed
to be expanded by third-party libraries and software. For example, with a deploy
order, AngularFire is already using these new capabilities.
2 New Unit Test Helpers were introduced so that we can upgrade Angular Project to
Unit Test Angular Service
RxJS 6
- Angular 6 makes use of RxJS 6 internally, RxJS released a library called rxjs-compat,
that allows you to still using one of the “old” syntaxes.
Elements:
lets you wrap your Angular components as Web Components and embed them in a
non-Angular application
i18n (internationalization):
Without having to build the application once per locale, any Angular application can
have “runtime i18n”
Tree-shakeable providers:
switchMap operator will cancel any previous inner observables and switch to the new
one when a new value is emitted from the outer observable. The main idea here is to
only have one inner observable active at a time, when an inner observable is
subscribed, any previous inner observables are unsubscribed.
concatMap operator will preserve the order of emissions, so it will wait for an inner
observable to complete before subscribing to the next one. This is useful when the
order of inner observables is important.
mergeMap operator will subscribe to all inner observables regardless of the outer
observable's emissions. It will merge the emissions of all inner observables and emit
them to the final stream, and it allows multiple inner observables to emit values at the
same time.
outerObservable.pipe(
concatMap(val => of(val, val + 1))
).subscribe(console.log)
// output: 1,2,2,3,3,4
outerObservable.pipe(
mergeMap(val => of(val, val + 1))
).subscribe(console.log)
// output: 1,2,2,3,3,4