How do I force a refresh on an Observable service in Angular2?

The way I've handled this problem so far has been to use an intermediary. this.userService.getUsers() returns an Rx.BehviorSubject which is initialized on the return of the http observable.

Something close to this:

getUsers() : BehaviorSubject<UserModel[]> {
  return this.behaviorSubject;
}
updateUsers() {
    this.http.get('http://localhost:3000/api/user')
                    .map((res: Response) => <UserModel[]>res.json().result)
                    .catch((error: any) => Observable.throw(error.json().error || 'Internal error occurred'))
                    .subscribe((value) => {
                      this.behaviorSubject.next(value)});
}

In order for an observable to be able to provide values after initial Http observable was completed, it can be provided by RxJS subject. Since caching behaviour is desirable, ReplaySubject fits the case.

It should be something like

class UserService {
  private usersSubject: Subject;
  private usersRequest: Observable;
  private usersSubscription: Subscription;

  constructor(private http: Http) {
    this.usersSubject = new ReplaySubject(1);
  }

  getUsers(refresh: boolean = false) {
    if (refresh || !this.usersRequest) {
      this.usersRequest = this.http.get(...).map(res => res.json().result);

      this.usersRequest.subscribe(
        result => this.usersSubject.next(result),
        err => this.usersSubject.error(err)
      );
    }

    return this.usersSubject.asObservable();
  }
  onDestroy() {
    this.usersSubscription.unsubscribe();
  }
}

Since the subject already exists, a new user can be pushed without updating the list from server:

this.getUsers().take(1).subscribe(users => 
  this.usersSubject.next([...users, newUser])
)

Tags:

Angular

Rxjs