Advanced RxJS Patterns in Angular
Advanced RxJS Patterns in Angular
RxJS is a powerful tool for handling reactive programming in Angular applications. Beyond basic observables, RxJS provides advanced patterns that optimize performance, enhance user experience, and simplify complex workflows.
What You Will Learn
- Implementing Infinite Scrolling with RxJS
- Optimizing Performance with
shareReplay - Handling User Authentication Streams
1. Implementing Infinite Scrolling with RxJS
Infinite scrolling is a common UI pattern where more data loads automatically as the user scrolls. Instead of making multiple API requests unnecessarily, we can use RxJS with Intersection Observer for an optimized experience.
๐ฆ Service: Fetch Posts
@Injectable({ providedIn: 'root' })
export class PostService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) {}
getPosts(page: number, limit: number): Observable<any> {
return this.http.get(`${this.apiUrl}?_page=${page}&_limit=${limit}`);
}
}
๐ Component: Infinite Scroll
@Component({
selector: 'app-infinite-scroll',
template: `
<div *ngFor="let post of posts">
{{ post.title }}
</div>
<div #loadMore>Loading...</div>
`
})
export class InfiniteScrollComponent implements AfterViewInit {
@ViewChild('loadMore', { static: false }) loadMore!: ElementRef;
posts: any[] = [];
currentPage = 1;
limit = 10;
constructor(private postService: PostService) {}
ngAfterViewInit(): void {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
this.loadMorePosts();
}
});
observer.observe(this.loadMore.nativeElement);
}
loadMorePosts() {
this.postService.getPosts(this.currentPage++, this.limit).subscribe(data => {
this.posts = [...this.posts, ...data];
});
}
}
✅ Why This Works:
- Only fetches data when user scrolls to the end.
- Uses Intersection Observer API to efficiently monitor scroll position.
2. Optimizing Performance with shareReplay
shareReplay caches emitted values to prevent repeated API calls. This enhances performance, especially when the same data is needed by multiple components.
๐ฆ User Service with Caching
@Injectable({ providedIn: 'root' })
export class UserService {
private userData$: Observable<any>;
constructor(private http: HttpClient) {
this.userData$ = this.http.get('https://api.example.com/user').pipe(
shareReplay(1) // Cache the latest response
);
}
getUser(): Observable<any> {
return this.userData$;
}
}
๐ Component Usage
@Component({
selector: 'app-user',
template: `
{{ user$ | async | json }}
`
})
export class UserComponent implements OnInit {
user$ = this.userService.getUser();
constructor(private userService: UserService) {}
ngOnInit() {}
}
✅ Benefits:
- Prevents duplicate API calls.
- Improves performance by caching.
- Ideal for shared data like user profiles.
3. Handling User Authentication Streams
BehaviorSubject is great for managing authentication state across components. It always returns the latest value upon subscription.
๐ Auth Service
@Injectable({ providedIn: 'root' })
export class AuthService {
private authState = new BehaviorSubject<boolean>(false);
authState$ = this.authState.asObservable();
login() {
setTimeout(() => this.authState.next(true), 1000); // Simulate login
}
logout() {
this.authState.next(false);
}
}
๐ Auth Component
@Component({
selector: 'app-auth',
template: `
<button (click)="login()">Login</button>
<button (click)="logout()">Logout</button>
`
})
export class AuthComponent {
auth$ = this.authService.authState$;
constructor(private authService: AuthService) {}
login() { this.authService.login(); }
logout() { this.authService.logout(); }
}
✅ Advantages:
- Real-time updates to all components.
- Cleaner state management without manual event emitters.
๐งพ Summary of Patterns
| Pattern | Use Case |
|---|---|
| Infinite Scrolling | Lazy-load data as the user scrolls |
shareReplay(1) |
Cache shared data, avoid repeated calls |
| BehaviorSubject for Auth | Global login/logout state management |
๐ Bonus Tips
- Use interfaces for type safety (e.g.,
Post,User). - Include StackBlitz demo links for live example trials.
- Watch out for memory leaks with
shareReplayon hot observables. - Refer to official Angular and RxJS docs for best practices.
Comments
Post a Comment