A RxJS takeWhen operator

If you needed to poll a service and then take the response only when a specific property of the response was equal to a predicate, then the following RxJS operator might help you.

function takeWhen<T>(predicate: (value: T, index: number) => boolean) {
  return (source: Observable<T>): Observable<T> => source.pipe(filter(predicate), take(1));
}

Example:

interval(500).pipe(
  concatMap(() => this.http.post(...)),
  takeWhen((res: IRpcBgResponse) => {
    return res.running === false;
  })
);

Dynamically inject routes in lazy loaded modules using Angular 11

If you would like to dynamically inject routes in lazy loaded modules in your Angular 11 app, then you need to do the following.

Make sure your service that is responsible for loading the route configuration via HTTP from the server is loading while the app is bootstrapped. This way we can be sure the route configuration is available after the app is bootstrapped.

const routes: Routes = [
  ...,
  { path: '**', redirectTo: '/404' }
];

@NgModule({
  exports: [RouterModule],
  imports: [
    RouterModule.forRoot(routes, {
      useHash: true
    })
  ],
  providers: [
    RouteConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: (routeConfigService: RouteConfigService) => {
        return () => {
          return routeConfigService.load().toPromise();
        };
      },
      multi: true,
      deps: [RouteConfigService]
    }
  ]
})
export class AppRoutingModule {}

You also need to ensure that your service is a singleton across the whole app.

@NgModule({
  declarations: [],
  imports: [...],
  exports: [...]
})
export class CoreModule {
  static forRoot(): ModuleWithProviders<CoreModule> {
    return {
      ngModule: CoreModule,
      providers: [
        RouteConfigService
      ]
    };
  }
}
@NgModule({
  declarations: [AppComponent],
  imports: [
    ...
    CoreModule.forRoot(),
    AppRoutingModule
  ],
  providers: [...],
  bootstrap: [AppComponent]
})
export class AppModule {}

And finally append the following provider in your lazy loaded module.

const routes: Routes = [
  ...
];

@NgModule({
  exports: [RouterModule],
  imports: [RouterModule.forChild(routes)],
  providers: [
    {
      provide: ROUTES,
      multi: true,
      useFactory: (routeConfigService: RouteConfigService) => {
        routeConfigService.inject('someArgsToIdentifyWhatToInject', routes);
        return routes;
      },
      deps: [RouteConfigService]
    }
  ]
})
export class MyLayzRoutingModule {}
@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...,
    MyLayzRoutingModule
  ]
})
export class LazyModule {}

PAM feature request for PHP8

Today i created a feature request for PHP8 because i fear that the new upcoming major release will not support PAM anymore. With PHP7 this is already a pain because the PAM PECL extension needs to be patched to get it working. I fear this workaround will become a dead end for PHP8. This will be a major issue because OMV is requiring this feature. And i don’t think OMV is the only one that wants to use PAM for authentication. IMO this is an essential requirement for a programming language that is used in professional applications.

Hopefully this issue will become a broader attention due this blog post and feature request to increase the possibility to fully integrate PAM support in PHP8. If you want to support that please feel free to add a comment to the feature request.