Skip to content

Instantly share code, notes, and snippets.

@1UC1F3R616
Last active March 30, 2024 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1UC1F3R616/8a87d60fc104581ac912da81c93f3be9 to your computer and use it in GitHub Desktop.
Save 1UC1F3R616/8a87d60fc104581ac912da81c93f3be9 to your computer and use it in GitHub Desktop.

Behavioural Subject

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

@Injectable({
  providedIn: 'root'
})
export class ThemeService {
  // Initial theme is set to 'light'
  private theme = new BehaviorSubject<string>('light');

  // Observable stream for theme changes
  public theme$ = this.theme.asObservable();

  constructor() { }

  // Method to set a new theme
  setTheme(newTheme: string) {
    this.theme.next(newTheme);
  }

  // Method to get the current theme value directly
  getCurrentTheme() {
    return this.theme.value;
  }
}

In your component, you could subscribe to the theme$ observable to reactively update the UI whenever the theme changes:

import { Component, OnInit } from '@angular/core';
import { ThemeService } from './theme.service';

@Component({
  selector: 'app-theme-switcher',
  template: `
    <button (click)="toggleTheme()">Toggle Theme</button>
    <div>Current Theme: {{ currentTheme }}</div>
  `,
})
export class ThemeSwitcherComponent implements OnInit {
  currentTheme: string;

  constructor(private themeService: ThemeService) {}

  ngOnInit() {
    this.themeService.theme$.subscribe(theme => {
      this.currentTheme = theme;
    });
  }

  toggleTheme() {
    const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
    this.themeService.setTheme(newTheme);
  }
}

Combine Latest

import { combineLatest, of } from 'rxjs';
import { startWith } from 'rxjs/operators';

// Simulate the search query Observable
const searchQuery$ = of('shirt').pipe(startWith(''));

// Simulate the selected category Observable
const selectedCategory$ = of('men').pipe(startWith('all'));

// Use combineLatest to combine the latest values emitted by both Observables
const combined$ = combineLatest([searchQuery$, selectedCategory$]);

// Subscribe to the combined Observable to get the latest [query, category] arrays
combined$.subscribe(([query, category]) => {
  console.log(`Performing search for query "${query}" in category "${category}"`);
});

When combined$ is subscribed to, it internally subscribes to both searchQuery$ and selectedCategory$, causing them to emit their values. Because combineLatest subscribes to its input Observables as part of its operation.

startWith is used to ensure that both searchQuery$ and selectedCategory$ Observables emit an initial value.

Usecases

Combining form input values to enable or disable a submit button based on their contents.

Triggering a request to fetch data based on a combination of filters that users can change.

Synchronizing multiple asynchronous tasks that depend on each other's most recent results.

Key Takeaways

combineLatest is ideal for combining multiple streams of data that may update independently.

It ensures that you always work with the latest values from each of the input streams.

It starts emitting only after each input Observable has emitted at least once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment