Search code examples
rxjsobservable

Fetch more data in RxJs


I have some problem with apply fetching "more" data using fromFetch from rxjs. I have project with React and RXJS. Currently I'm using something like this:

  const stream$ = fromFetch('https://pokeapi.co/api/v2/pokemon?limit=100', {
    selector: response => response.json()
  }).subscribe(data => console.log(data));

But! I would like to change limit dynamically, when I click button or even better - when I scroll to the very bottom of my website. How to make something like this? So that, based on some interaction, the limit would change?


Solution

  • The way your observable work in your case it's a request-response. You're declaring stream$ to be an observable that when someone subscribes it will make a request with limit=100.

    There are different ways of solving this... The most straightforward would be:

    const getPokemon$ = limit =>
      fromFetch('https://pokeapi.co/api/v2/pokemon?limit=' + limit, {
        selector: response => response.json()
      });
    
    const MyComponent = () => {
      // ...
      
      useEffect(() => {
        const sub = getPokemon$(limit).subscribe(res => console.log(res));
    
        return () => sub.unsubscribe();
      }, [limit])
    
      // ...
    }
    

    Another option, probably a bit more reactive but harder to follow for others, would be to declare another stream which sets the limit:

    const limit$ = new BehaviorSubject(100)
    
    const pokemon$ = limit$.pipe(
      switchMap(limit => fromFetch('https://pokeapi.co/api/v2/pokemon?limit=' + limit, {
        selector: response => response.json()
      }))
    );
    
    // In your component
    
    const MyComponent = () => {
      // ...
    
      useEffect(() => {
        const sub = pokemon$.subscribe(res => console.log(res));
    
        return () => sub.unsubscribe();
      }, [])
    
      changeLimit = (newLimit) => limit$.next(newLimit)
    
      // ...
    }
    

    In this other solution, you're declaring how pokemon$ should react to changes on limit$, and you can set limit$ from any other component you want.