Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

APP_INITIALIZER in library causes "Lambda not supported" error

When defining an APP_INITIALIZER in a library module, the build fails with the Lambda not supported error. The build error is thrown when the function is exported as per docs:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { MylibComponent } from './mylib.component';

export function myLibInit() {
  return () => console.log('Hi from exported function');
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      multi: true,
      useFactory: myLibInit
    }
  ]
})
export class MylibModule { }

The build error is thrown in both dev and prod.

I have alternatively also tried defining the factory function using ES6 object method shorthand notation:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { MylibComponent } from './mylib.component';

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      multi: true,
      useFactory() {
        return () => console.log('Hi from ES6 object method shorthand')
      }
    }
  ]
})
export class MylibModule { }

This passes both the dev and prod build, but the app throws the ERROR TypeError: this.appInits[r] is not a function error at runtime when the library and app is built with the prod flag.

How does one correctly use the APP_INITIALIZER in a library and not get build or runtime errors?

A reproduction can be found here:

  1. git clone https://github.com/samherrmann/angular-sandbox.git
  2. cd angular-sandbox
  3. git checkout lambda-not-supported
  4. npm install
  5. npm run build

GitHub issue regarding this problem can be found here.

like image 349
Sam Herrmann Avatar asked Aug 22 '18 23:08

Sam Herrmann


1 Answers

What I understand is that while compiling, the typescript compiler tries to resolve as much as it can.

So when you are doing it like this:

export function myLibInit() {
  return () => console.log('Hi from exported function');
}

It tries to resolve it to simply () => console.log('Hi from exported function'); because nothing else is being done in the function.

Now, let us make the function do a little more:

export function myLibInit() {
  var x = 2+2; //let us just do something to keep this original function
  return () => console.log('Hi from exported function');
}

This one compiles without error, because it is not returning the only and exactly lamda function.

Also the below one works as well because there is an extra assignment.

export function myLibInit() {
  var x = () => console.log('Hi from exported function');
  return x;
}

You can of course return a promise.

I did see your links to some tutorials and they are doing exactly what you have problem with and I think they are probably old or not done with the version of angular you are working. Because documentation clearly states that

"The compiler does not currently support function expressions or lambda functions. "

And they are doing somewhat similar to that. One reason could be that they actually never performed the build because it doesn't give you error on ng serve

I can see that they have closed your issue on github but I think they should review it because of my above explanation.

like image 143
EresDev Avatar answered Nov 10 '22 05:11

EresDev