0

I'm having the same issue with RXJS

I'm using angular-auth-oidc-client. To load several configurations, I'm using this factory.

const httpLoaderFactory = (configService: CustomConfigService) => {
  return new StsConfigHttpLoader(configService.getConfigs$())
}

@NgModule({
  imports:[
    AuthModule.forRoot({
        loader: {
            provide: StsConfigLoader,
            useFactory: httpLoaderFactory,
            deps: CustomConfigService
        }
    })
],
//...
})
export class AuthConfigModule{}

This is how the service looks like.

export class CustomConfigService{

getConfigs$(): Observable<OpenIdConfiguration>[] {
    //make call to the backend 
    //generate OpenIdConfiguration object for each client
    //return an array of Observable<OpenIdConfiguration>
  }
 }

To request the list of clients from the backend, I will need to use observable or promise.

The problem is that when I can't use the await keyword without decorating the method with the async keyword as well.

getConfigs$(): Observable<OpenIdConfiguration>[] {
    return await somePromise(); /// needs to decorate the method with async
}

The problem with that is the initial calling method is complaining about the type being Promise<T> instead of T, in this case Observable<OpenIdConfiguration>[].

Using then promise won't work

getConfigs$(): Observable<OpenIdConfiguration>[] {
  let result;
  somePromise()
    .then((r) => result = r);

    return result; //this will run before the promise resolves...!!!!!
}

I'm really stuck. Is there a workaround on this situation?

Thanks for helping

EDIT

return this._store.pipe(
  select(mySelector), //request data
  map((data) => this.transformToConfig(data)
);

if I return this as it is, it will be an Observable<Observable<OpenIdConfiguration>[]>. The calling method expects a T, i.e. an array of observables.

Richard77
  • 20,343
  • 46
  • 150
  • 252
  • Async functions always returns a promise. What's the problem with changing the return type to Promise? – James Oct 06 '22 at 20:28
  • Look at the code I posted. The `factory` is not an async function. If I try to decorate it with the `async` keyword, then I get an error. However, without async, I can't use `await` either to resolve the value. So I'm stuck. – Richard77 Oct 06 '22 at 20:39
  • To convert a promise to an observable, use the `from` function in rxjs. `getConfigs$(): Observable[] { return from(somePromise()); }` – Nicholas Tower Oct 06 '22 at 20:41
  • Converting the promise to an observable won't help either as I will end up with `Observable[]>` instead of `Promise[]>`. The library is expecting an array of observable like this `Observable[]` – Richard77 Oct 06 '22 at 20:44
  • @NicholasTower, plus take a look at the edit. – Richard77 Oct 06 '22 at 20:52
  • @Richard77 That is an observable for an array of configurations, not an array of observables. – Bergi Oct 07 '22 at 01:26
  • @Richard77 You can easily flatten two nested observables. Or just use `flatMap` instead of `map` in the first place. – Bergi Oct 07 '22 at 01:27

0 Answers0