user3230660
user3230660

Reputation:

How to use Angular factory provider?

In the code below I am trying to create an instance of PermissionService using a factory provider.

I get this error when I try to call a method on PermissionService in the class that consumes it:

Uncaught (in promise): TypeError: this.permissionService.isAdmin is not a function

What am I doing wrong?

using Angular 9.1.1

Reference: Angular Async Factory Provider

app.module.ts

providers: [
  {provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
  GlobalService,
  {provide: ErrorHandler, useClass: ClientErrorService },
  {provide: PermissionService, useFactory: async (h:HttpClient) => {
    const permissionsService = new PermissionService(h);
    await permissionsService.initialization;
    return permissionsService;
  }, deps:[HttpClient]}
  ],

PermissionService.ts

@Injectable({
  providedIn: 'root'  // singleton
})
export class PermissionService {
  public initialization : Promise<void>;  
  private _isAdmin : boolean;
  private appPermissionsDict : object;
  private dataPermissionsDict : object;

  baseUrl = environment.baseUrl + 'permission';

  constructor(private http: HttpClient) {
    this.initialization = this.init();
  }


  async init()
  {
    const data = await ...
  }

  isAdmin() : boolean { return this._isAdmin; }
}

UsersGroupsListComponent.ts // consumes permissionService

export class UsersGroupsListComponent implements OnInit {

  IsAdmin: boolean = false;

  constructor(private globalSvc: GlobalService,
    private administrationSvc: AdministrationService,
    private userSvc: UserService,
    private permissionService: PermissionService,
    private editDialog: MatDialog) {
        this.IsAdmin = this.permissionService.isAdmin();  // Error here
  }
}

Upvotes: 0

Views: 285

Answers (1)

Andrei
Andrei

Reputation: 12036

you can't build instance of a service via async factory. the example you linked is an APP_INITIALIZER usage, which will block your app from start untill some promise is resolved. In yout example correct usage would be

export const waitForPermissionServiceInit = (serv: PermissionService) =>
  () => serv.initialization;
...
 providers: [
    PermissionService,
    {
      provide:      APP_INITIALIZER,
      useFactory:   waitForPermissionServiceInit,
      deps:         [PermissionService],
      multi:        true,
    },
  ],

so PermissionService will be constructed immediately, but app won't start, untill it is initialized

Upvotes: 1

Related Questions