charliebrownie
charliebrownie

Reputation: 6097

Angular: Need to resolve a chain of several operations (Observable)

I want to have a bunch of data ready the very first thing after a user logs in my app (keeping it cached in a Service).

I thought implementing this data-loading logic before resolving the parent route the user will be redirected to if login is successful, as a Resolver.

To be more specific: before showing the user's home page I would like to have a list of data already loaded and, if the list is not empty, have the first element of that list set as the selected element by default. So, this means, two Services:

And the following Resolver:

@Injectable()
export class ItemsResolver implements Resolve<any> {

  constructor(
    private itemSelectedService: ItemSelectedService,
    private itemsService: ItemsService
  ) { }

  resolve() {
    this.itemsService.getAll()
      .subscribe((items) => {
        if (items.length > 0) {
          this.itemSelectedService.setAsSelected(items[0]);
        }
      });
  }

}

As #resolve() needs to return an Observable (return this.itemsService.getAll() would have just been enough...) but I'm not returning any because I need to subscribe and call itemSelectedService#setAsSelected() once the item list has been fetched asynchronously... what would be the right way to achieve the desired behavior?

Upvotes: 1

Views: 136

Answers (2)

user2033671
user2033671

Reputation:

Try giving it a tap

resolve() {
    return this.itemsService.getAll()
    .pipe(
         tap(
             filter(items=>items.length > 0)
             do(items=>this.itemSelectedService.setAsSelected(items[0]))
         )
    );
}

do / tap
Transparently perform actions or side-effects, such as logging. https://www.learnrxjs.io/operators/utility/do.html

Upvotes: 1

blazehub
blazehub

Reputation: 1960

You can use flatmap to resolve the observable in chain

@Injectable()
export class ItemsResolver implements Resolve<any> {

  constructor(
    private itemSelectedService: ItemSelectedService,
    private itemsService: ItemsService
  ) { }

  resolve() {
    return this.getAll()
      .pipe(
        flatmap(items => this.setSelectService(item[0]))
      )
  }

  getAll() {
    return this.itemsService.getAll();
  }

  setSelectService(item) {
    return this.itemSelectedService.setAsSelected(item);
  }

}

Upvotes: 0

Related Questions