π Customizing RxJS with Your Own Operators
#angular #rxjs
β Article link: https://javascript.plainenglish.io/customizing-rxjs-with-your-own-operators-eb9094162202
#angular #rxjs
β Article link: https://javascript.plainenglish.io/customizing-rxjs-with-your-own-operators-eb9094162202
This media is not supported in your browser
VIEW IN TELEGRAM
π Simple modal in Angular
#angular #rxjs #standalone #modal #ngTemplate
β Article link: https://medium.com/@greenFlag/how-to-easily-and-quickly-create-a-modal-in-angular-a2f82d5c11f6
π Example: https://stackblitz.com/edit/stackblitz-starters-6pmxgl?file=src%2Fapp%2Fapp.component.ts
#angular #rxjs #standalone #modal #ngTemplate
β Article link: https://medium.com/@greenFlag/how-to-easily-and-quickly-create-a-modal-in-angular-a2f82d5c11f6
Please open Telegram to view this post
VIEW IN TELEGRAM
π1
π Custom RxJS operators 1/7: "Π‘ache operator"
#angular #rxjs #cache
Often an RxJS stream represents an http request β a stream that emits a single value and completes. Performance-wise, it is a good practice to cache a response from a server for a certain amount of time. The built-in share operator can be configured to provide a caching mechanism with a Time To Live (TTL) for a response.
operator
#angular #rxjs #cache
Often an RxJS stream represents an http request β a stream that emits a single value and completes. Performance-wise, it is a good practice to cache a response from a server for a certain amount of time. The built-in share operator can be configured to provide a caching mechanism with a Time To Live (TTL) for a response.
operator
import { ... } from 'rxjs';
function cache<T>(ttl: number = Infinity): MonoTypeOperatorFunction<T> {
return share({
connector: () => new ReplaySubject(1),
resetOnComplete: () => timer(ttl),
});
}π₯1
π Custom RxJS operators 2/7: "filterNil operator"
#angular #rxjs #filterNil
It is quite common to filter out null and undefined values from the resulting stream. Obviously, the built-in filter operator is the right tool to do the job, however in order to ensure proper type narrowing, the predicate function has to be a user-defined type guard. Therefore, it makes sense to encapsulate it into a custom RxJS operator.
operator
#angular #rxjs #filterNil
It is quite common to filter out null and undefined values from the resulting stream. Obviously, the built-in filter operator is the right tool to do the job, however in order to ensure proper type narrowing, the predicate function has to be a user-defined type guard. Therefore, it makes sense to encapsulate it into a custom RxJS operator.
operator
import { filter, OperatorFunction } from 'rxjs';
function filterNil<T>(): OperatorFunction<T, NonNullable<T>> {
return filter((v): v is NonNullable<T> => v != undefined);
}π1π₯1
π Custom RxJS operators 3/7: "firstMatching operator"
#angular #rxjs #firstMatching
For most use cases, the task can be accomplished at least in two ways. However, there is a subtle difference when the source stream completes without having emitted a value that meets requirements. The detailed explanation can be found in one of my RxJS hints. The operator in question allows to choose a given strategy to handle such scenario based on the required argument.
operator
#angular #rxjs #firstMatching
For most use cases, the task can be accomplished at least in two ways. However, there is a subtle difference when the source stream completes without having emitted a value that meets requirements. The detailed explanation can be found in one of my RxJS hints. The operator in question allows to choose a given strategy to handle such scenario based on the required argument.
operator
import { of, MonoTypeOperatorFunction, pipe, first, filter, take } from 'rxjs';
function firstMatching<T>(
predicateFn: (v: T) => boolean,
required: boolean = false
): MonoTypeOperatorFunction<T> {
return required ? first(predicateFn) : pipe(filter(predicateFn), take(1));
}π₯1
π Custom RxJS operators 4/7: "
#angular #rxjs #withLifecycle
Debugging RxJS code can be a challenge. Fortunately, the built-in tap operator provides a way to track lifecycle events for a stream.
operator
withLifecycle operator"#angular #rxjs #withLifecycle
Debugging RxJS code can be a challenge. Fortunately, the built-in tap operator provides a way to track lifecycle events for a stream.
operator
export function withLifecycle<T>(
streamId: string
): MonoTypeOperatorFunction<T> {
return tap({
subscribe: () => console.log(`[${streamId}]: subscribed`),
unsubscribe: () => console.log(`[${streamId}]: unsubscribed`),
finalize: () => console.log(`[${streamId}]: emitted final value`),
});
}
β€1
π Custom RxJS operators 5/7: "
#angular #rxjs #pollWhile
The good old polling mechanism is still quite relevant in applications which rely on data that changes over a period of time. Letβs consider a scenario when an application has to make http requests in a certain time interval until an http response body fulfils a given condition, e.g. analysis status is set to completed. The built-in repeat operator combined with a limiting operator allows to accomplish the goal with a few lines of code.
operator
pollWhile operator"#angular #rxjs #pollWhile
The good old polling mechanism is still quite relevant in applications which rely on data that changes over a period of time. Letβs consider a scenario when an application has to make http requests in a certain time interval until an http response body fulfils a given condition, e.g. analysis status is set to completed. The built-in repeat operator combined with a limiting operator allows to accomplish the goal with a few lines of code.
operator
interface PollWhileConfig<T> {
predicateFn: (v: T) => boolean;
delay: number;
count?: number;
lastOnly?: boolean;
}
function pollWhile<T>({
predicateFn,
delay,
count = Infinity,
lastOnly = false,
}: PollWhileConfig<T>): MonoTypeOperatorFunction<T> {
const limiter = lastOnly
? pipe(
filter((v: T) => !predicateFn(v)),
take(1)
)
: takeWhile(predicateFn, true);
return pipe(repeat({ delay, count }), limiter);
}π₯1
π Custom RxJS operators 6/7: "
#angular #rxjs #retryForStatus
The built-in retry operator allows to resubscribe to the source stream once an error has been thrown. It is possible to make a decision whether or not to retry based on the information contained in the error object. In turn, when it comes to streams that represent an http request, the operator can be configured to call an API again only for certain response statuses.
operator
retryForStatus operator"#angular #rxjs #retryForStatus
The built-in retry operator allows to resubscribe to the source stream once an error has been thrown. It is possible to make a decision whether or not to retry based on the information contained in the error object. In turn, when it comes to streams that represent an http request, the operator can be configured to call an API again only for certain response statuses.
operator
interface ErrorWithStatus extends Error {
status: number;
}
interface RetryForStatusConfig {
retryableStatuses: number[];
delay: number;
count?: number;
}
function retryForStatus<T>({
retryableStatuses,
delay,
count = Infinity,
}: RetryForStatusConfig): MonoTypeOperatorFunction<T> {
return retry({
count,
delay: (err: ErrorWithStatus, retryCount) =>
retryableStatuses.includes(err.status)
? timer(retryCount * delay)
: throwError(() => err),
});
}π₯1
π Custom RxJS operators 7/7: "
#angular #rxjs #toLatestFrom
The built-in
operator
toLatestFrom operator"#angular #rxjs #toLatestFrom
The built-in
withLatestFrom operator allows to add data from supplementary streams to the source stream. However, sometimes the source stream is just a trigger to perform a certain action for which data from supplementary streams is needed. As a result, the array of elements in the output stream contains a dummy first element. A better solution is to neglect the value from the trigger.operator
function toLatestFrom<T, D1>(d1$: ObservableInput<D1>): OperatorFunction<T, D1>;
function toLatestFrom<T, D1, D extends unknown[]>(
d1$: ObservableInput<D1>,
...data$: [...ObservableInputTuple<D>]
): OperatorFunction<T, [D1, ...D]>;
function toLatestFrom<D1, D extends unknown[]>(
d1$: ObservableInput<D1>,
...data$: [...ObservableInputTuple<D>]
) {
return pipe(
withLatestFrom(d1$, ...data$),
map(([_, ...data]) => (data.length === 1 ? data[0] : data))
);
}
π₯1
π Tracking an inactive user using RXJS
#angular #rxjs
β Article link: https://designtechworld.medium.com/angular-tracking-an-inactive-user-using-rxjs-in-built-and-custom-events-33d2e95fd167
#angular #rxjs
User inactivity can be defined as a period during which a user does not interact with the application. Tracking this inactivity helps in various scenarios, such as optimizing resource usage, enhancing security, and providing a better user experience.
// inactivity.service.ts
import { Injectable } from '@angular/core';
import { Observable, fromEvent, timer } from 'rxjs';
import { mergeMap, mapTo } from 'rxjs/operators';
@Injectable({ providedIn: 'root'})
export class InactivityService {
public trackInactivity(
duration: number
): Observable<boolean> {
const mouseMove$ = fromEvent(document,'mousemove')
.pipe(mapTo(true));
const keyDown$ = fromEvent(document,'keydown')
.pipe(mapTo(true));
return timer(0, duration)
.pipe(
mergeMap(() => mouseMove$ || keyDown$)
);
}
}
β Article link: https://designtechworld.medium.com/angular-tracking-an-inactive-user-using-rxjs-in-built-and-custom-events-33d2e95fd167
π₯1
πManaging the Sticky Navigation: Angular, Tailwind, and RxJS
#angular #rxjs #tailwind #navbar #ui_element
β Article link
#angular #rxjs #tailwind #navbar #ui_element
Explanation:
β `public readonly isSticky$ = fromEvent(window, 'scroll').pipe(...):` This defines the isSticky$ observable using RxJS operators. It listens for scroll events on the window, maps them to the vertical scroll position (window.scrollY), filters out consecutive duplicate values, and then maps the scroll position to a boolean value indicating whether the scroll position is greater than 24 (assuming 24 is a threshold value for determining when the navigation bar should become sticky).
β `distinctUntilChanged()`: This operator filters out consecutive duplicate values emitted by the observable.
β `map((scrollTop: number) => scrollTop > 24)`: This operator maps the scroll position (scrollTop) to a boolean value, indicating whether the user has scrolled past a certain threshold (24 in this case).
β `(isSticky$ | async) === true`: This condition checks if the value emitted by the isSticky$ is true or not. Which makes it convenient since you donβt have to unsubscribe the observable.
β `sticky top-0 z-10 shadow-lg opacity-95 bg-white`: These classes from TailWind will help enhance the sticky experience when the users scroll down.
β Article link
π Infinite Scroll Component in Angular
#angular #rxjs #ui_element #infiniteScroll
β Article linkπ Code Link
#angular #rxjs #ui_element #infiniteScroll
β Article link
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
π Internet connection monitoring in Angular
#angular #rxjs
β οΈ The example is for presentation purposes only and can be refactored.
β Article link
#angular #rxjs
β οΈ The example is for presentation purposes only and can be refactored.
β Article link
π1
π2
π Data fetching patterns in Angular
#angular #rxjs
β Article link
#angular #rxjs
The idea of the Asynchronous State Handler is to combine asynchronous operations with an explicit loading and error state. While an asynchronous operation is running, the status is loading. It ends either in an error state or with the actual result of the operation. Thinking of a generic operation result T, the Asynchronous State Handler is a function that returns T | 'loading' | 'error'. Using a union type underlines that the result is always exactly one state. Using string literal types for loading and error state is simple but descriptive. They can be replaced by other types if required.
β Article link
#angular #rxjs #shareReplay #let
β Article link
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
β€3
#rxjs #observeOn #asyncScheduler
One common scheduler in RxJS is the observeOn() operator. The observeOn() operator is used to specify the scheduler on which an observable should emit its values.
In this example, the from() function is used to create an observable that emits the values 1, 2, and 3. The observeOn() operator is then used to specify that the observable should emit its values on the async scheduler, which will cause the values to be emitted asynchronously. The asyncScheduler is a common scheduler in RxJS that schedules tasks to be executed asynchronously using setTimeout().
β Article link
Please open Telegram to view this post
VIEW IN TELEGRAM
π1
#angular #rxjs #share #publish #shareReplay
What is Multicasting?
Multicasting allows an observable to share its execution across multiple subscribers, so that all subscribers receive the same emitted data at the same time. By default, observables in RxJS are βunicast,β meaning each subscription creates a separate execution of the observable. This can lead to multiple API calls or side effects if several components subscribe to the same observable.
Multicasting ensures that only one execution occurs, regardless of how many subscribers are attached to the observable. This is particularly useful in scenarios where expensive operations (such as HTTP requests) should be shared across multiple components without being re-executed multiple times.
β Article link
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
π5
π7