Getting Started with RxJS
In this tutorial, we’ll cover the basic principles of RxJS. Although RxJS is a standalone library, in the context of Angular it is installed and used by default. RxJS is involved in many Angular features, such as the HTTP client, reactive forms, and the router.
The core idea behind RxJS is reactive programming. Its main concepts are data streams, observables, and observers.
A simple example: when you click the “Buy” button, a new item is added to the cart, producing a data stream. The Cart component subscribes to these changes, which triggers data updates such as the total cost and the number of items.
A simple example: when you click the “Buy” button, a new item is added to the cart, producing a data stream. The Cart component subscribes to these changes, which triggers data updates such as the total cost and the number of items.
RxJS simplifies working with asynchronous code compared to callbacks and promises. In this tutorial, we’ll explore practical uses of RxJS, operators (a crucial part of working with streams), and other topics, such as hot and cold observables.
app.ts
import {Component, DestroyRef, inject, OnDestroy, OnInit} from '@angular/core';
import {User, UserService} from './user-service';
import {debounceTime, filter, Observable, of, Subject, Subscription, takeUntil} from 'rxjs';
import {AsyncPipe} from '@angular/common';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {UsersList} from './users-list/users-list';
@Component({
selector: 'app-root',
templateUrl: './app.html',
imports: [
ReactiveFormsModule,
AsyncPipe,
UsersList
],
styleUrl: './app.scss'
})
export class App implements OnInit {
protected users: User[] = [];
protected users$!: Observable<User[]>;
protected search = new FormControl<string>('');
protected sub = new Subscription();
protected destroy$!: Subject<any>;
public obs = of(1,2,3);
public subj = new Subject<number>();
protected destroyRef = inject(DestroyRef);
constructor(private userService: UserService) {
}
public ngOnInit() {
this.userService.getUsers().pipe(
takeUntilDestroyed(this.destroyRef)
).subscribe();
this.users$ = this.userService.getUsers();
this.search.valueChanges.pipe(
filter(query => !!query?.trim()),
debounceTime(500),
takeUntilDestroyed(this.destroyRef),
).subscribe()
// this.obs.subscribe(v => console.log('Подписчик первый', v));
// this.obs.subscribe(v => console.log('Подписчик второй', v));
this.subj.subscribe(v => console.log('Подписчик 1', v));
this.subj.next(1);
this.subj.subscribe(v => console.log('Подписчик 2', v));
this.subj.next(2);
}
protected addUser() {
const newUser = this.search.value;
if (newUser) {
const currentUsers = this.userService.users$.getValue();
currentUsers.push(newUser);
this.userService.users$.next(currentUsers);
}
}
}
app.html
<!--<ul>-->
<!-- @for (user of users; track user.id) {-->
<!-- <li>{{user.name}}</li>-->
<!-- }-->
<!--</ul>-->
@let users = users$ | async;
{{users?.length}}
<ul>
@for (user of users; track user.id) {
<li>{{user.name}}</li>
}
</ul>
<input type="text" [formControl]="search">
<button (click)="addUser()">Add user</button>
<div>
<app-users-list></app-users-list>
</div>
user-service.ts
import {inject, Injectable} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {BehaviorSubject, catchError, forkJoin, filter, fromEvent, map, Observable, of, ReplaySubject, Subject, tap} from 'rxjs';
export interface User {
id: number,
name: string;
username: string;
email: string;
address: Record<string, string>;
phone: string;
website: string;
company: Record<string, string>;
}
@Injectable({
providedIn: 'root',
})
export class UserService {
protected http = inject(HttpClient);
public users$ = new BehaviorSubject<string[]>([]);
getUsers() {
return this.http.get<User[]>('https://jsonplaceholder.typicode.com/users')
.pipe(
map(data => data),
)
}
}
user-list.ts
import {Component, OnInit} from '@angular/core';
import {JsonPipe} from '@angular/common';
import {UserService} from '../user-service';
@Component({
selector: 'app-users-list',
imports: [
JsonPipe
],
templateUrl: './users-list.html',
styleUrl: './users-list.scss',
})
export class UsersList implements OnInit{
protected users: string[] = [];
constructor(private usersService: UserService) {
}
public ngOnInit() {
this.usersService.users$.subscribe(res => this.users = res);
}
}
user-list.html
Users length: {{users | json}}
0 Comments