lampshade
lampshade

Reputation: 2796

How to fetch data again from an API after something changed in a component using Observables?

I have a DataServive, that fetches content from an API:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError, retry } from 'rxjs/operators';
import { environment } from 'src/environments/environment';

@Injectable()

export class DataService {
  this.request = {
     count: 10
  }

  constructor(private http: HttpClient) { }

  private handleError(error) {
    console.log(error);
  }

  public getData(count): Observable<any> {
    this.request.count = count;

    return this.http.post<any>(environment.api + '/path', this.request).pipe(
      map(response => {
        return response;
      }),
      catchError(error => {
        this.handleError(error);
        return [];
      })
    );
  }
}

This DataServie is consumned by a component like this:

ngOnInit() {
  const subscriber = this.dataService.getData(this.count).subscribe((data) => { this.data = data; });
}

And it works fine.


However the user is able to change the variable this.count (how many items should be displayed) in the component. So I want to get new data from the server as soon as this value changes.

How can I achieve this?

Of course I could call destroy on this.subscriber and call ngOnInit() again, but that dosn't seem like the right way.

Upvotes: 1

Views: 1233

Answers (2)

Julius Dzidzevičius
Julius Dzidzevičius

Reputation: 11000

Easiest ways is just to unsubscribe:

subscriber: Subscription;

ngOnInit() {
  this.makeSubscription(this.count);
}

makeSubscription(count) {
  this.subscriber = this.dataService.getData(this.count).subscribe((data) => { this.data = data; });
}

functionInvokedWhenCountChanges(newCount) {
  this.subscriber.unsubscribe();
  makeSubscription(newCount);
}

But because count argument is just a one number it means HTTP always asks for data from 0 to x. In this case, you can better create another subject where you can store previous results (so you don't need to make useless HTTP requests) and use that subject as your data source. That needs some planning on your streams, but is definitely the preferred way.

Upvotes: 2

Peter Kim
Peter Kim

Reputation: 1977

When the user changes count, call getData(count) again with the updated count value. Need to see your html file, but having a button with (click)="getData(count)" may help.

Upvotes: 0

Related Questions