Search code examples
angularangular2-observables

How to re-execute subscribed Observable in Angular


I have a service that fetches a list of users from the API server and caches it:

@Injectable({
  providedIn: 'root'
})
export class UsersService {

  constructor(private apiService: ApiService) {}

  users: UsersListInterface[] = null;

  getAll():Observable<UsersListInterface[]> {
    if (this.users !== null) {
      return of(this.users);
    }
    return this.apiService.get<UsersListApiInterface[]>(16, '').pipe(
      map((receivedData: UsersListApiInterface[]) => {
        this.users = receivedData.map(
          function(rawUser: UsersListApiInterface):UsersListInterface {
            return Object.assign({}, rawUser, {
              id: Number(rawUser.id)
            });
          }
        )
        return this.users;
      })
    );
  }

  add(newUser: UserVehicleDongleModel): Observable<string> {
    return this.apiService.post<ResultInterface>(6, 'create', newUser).pipe(
      map((receivedData: ResultInterface) => {
        this.users = null;
        return receivedData.result;
      })
    );
  }
}

Also, every time there is a new user added, the cache is cleared, so the next time a component requests a list of users, the service will re-query the API server.

I have a component that uses this service and manages a form to add/edit users. In the onInit event it subscribes to get all users. It stores the subscription to be able to unsubscribe from it in the ngOnDestroy event:

ngOnInit(): void {
    this.getUsersSubscription = this.usersService.getAll().subscribe(
        ((users) => {
            this.users = users;
        }),
        ((error: HttpErrorResponse) => {
            console.error(error);
            this.users = [];
        })
    )
}

ngOnDestroy(): void {
    if (this.getUsersSubscription) {
        this.getUsersSubscription.unsubscribe();
    }
}

onSubmit(add: NgForm) {
    if (add.valid) {
        if (this.selectedUser === null) {
            this.addUserSubscription = this.usersService.add(newUser).subscribe(
                () => {
                    // Refresh list of users?
                },
                (error: HttpErrorResponse) => {
                    console.error(error);
                }
            );
        } else {
            this.updateUserSubscription = this.usersService.update(newUser).subscribe(
                () => {
                    //
                },
                (error: HttpErrorResponse) => {
                    console.error(error);
                }
            );
        }
    }
}

Is there a way to re-use this subscription to pull the list of users after a new user has been added?


Solution

  • First of all there is no need to manually unsubscribe See this post

    Second, create a method and simply call it in your add user subscription.

    ngOnInit(): void {
        this.refreshUsers();
    }
    
    private refreshUsers(): void {
      this.usersService.getAll().subscribe(
            ((users) => {
                this.users = users;
            }),
            ((error: HttpErrorResponse) => {
                console.error(error);
                this.users = [];
            })
        )
    }
    
    
    
    
    onSubmit(add: NgForm) {
        if (add.valid) {
            if (this.selectedUser === null) {
                this.addUserSubscription = this.usersService.add(newUser).subscribe(
                    () => {
                        // Refresh list of users?
                        this.refreshUsers();
                    },
                    (error: HttpErrorResponse) => {
                        console.error(error);
                    }
                );
            } else {
                this.updateUserSubscription = this.usersService.update(newUser).subscribe(
                    () => {
                        //
                    },
                    (error: HttpErrorResponse) => {
                        console.error(error);
                    }
                );
            }
        }
    }