Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstracting @Injectable with Angular Ivy does not work #34721

Closed
GregOnNet opened this issue Jan 10, 2020 · 3 comments
Closed

Abstracting @Injectable with Angular Ivy does not work #34721

GregOnNet opened this issue Jan 10, 2020 · 3 comments
Labels
area: compiler Issues related to `ngc`, Angular's template compiler
Milestone

Comments

@GregOnNet
Copy link

GregOnNet commented Jan 10, 2020

馃悶 bug report

Affected Package

  • @angular/core
  • @angular/compiler
  • @angular/platform-browser-dynamic

Is this a regression?

  • It works, if Ivy is disabled.

Description

Without Ivy, it is possible to build an abstraction for @Injectable (e.g. for configuring the provider dynamically, enhancing the service class).

The following snippet shows an example how @Injectable can be wrapped.

export function InjectableEnhanced() {
  return <T extends new (...args: any[]) => InstanceType<T>>(target: T) => {
    Injectable({ providedIn: "root" })(target);
  };
}

Using the decorator @InjectableEnhanced (see above) does not work while Ivy is enabled. The following code snipped causes a runtime error (see "馃敟 Exception or Error").

@InjectableEnhanced() // -> does not work, having Ivy enabled
export class MyService {
  constructor() {}
}

馃敩 Minimal Reproduction

See error

git clone https://github.com/GregOnNet/ng-9-inject.git temp
cd temp
yarn
yarn start # open localhost:4200, see error in browser console

See it working

  • Turn off ivy in tsconfig.json
  • Execute yarn start --open to see it working

馃敟 Exception or Error


core.js:597 Uncaught Error: Angular JIT compilation failed: '@angular/compiler' not loaded!
  - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.
  - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?
  - Alternatively provide the compiler with 'import "@angular/compiler";' before bootstrapping.
    at getCompilerFacade (core.js:597)
    at Function.get (core.js:18078)
    at Module../src/app/my.service.ts (my.service.ts:20)
    at __webpack_require__ (bootstrap:79)
    at Module../src/app/app.component.ts (app.component.ts:1)
    at __webpack_require__ (bootstrap:79)
    at Module../src/app/app.module.ts (app.module.ts:1)
    at __webpack_require__ (bootstrap:79)
    at Module../src/main.ts (main.ts:1)
    at __webpack_require__ (bootstrap:79)

馃實 Your Environment

Angular Version:


Angular CLI: 9.0.0-rc.8
Node: 12.13.1
OS: darwin x64

Angular: 9.0.0-rc.8
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.0-rc.8
@angular-devkit/build-angular     0.900.0-rc.8
@angular-devkit/build-optimizer   0.900.0-rc.8
@angular-devkit/build-webpack     0.900.0-rc.8
@angular-devkit/core              9.0.0-rc.8
@angular-devkit/schematics        9.0.0-rc.8
@ngtools/webpack                  9.0.0-rc.8
@schematics/angular               9.0.0-rc.8
@schematics/update                0.900.0-rc.8
rxjs                              6.5.4
typescript                        3.6.4
webpack                           4.41.2

Anything else relevant?

@AndrewKushnir AndrewKushnir added area: compiler Issues related to `ngc`, Angular's template compiler comp: ivy labels Jan 10, 2020
@ngbot ngbot bot added this to the needsTriage milestone Jan 10, 2020
@alxhub
Copy link
Member

alxhub commented Jan 14, 2020

This is not supported in Angular.

It worked previously because @Injectable previously had no effect at compilation time. It existed to cause TypeScript to emit constructor metadata when compiling the class to allow for JIT compilation.

In Ivy, @Injectable is resolved at compilation time like every other Angular decorator, and thus cannot be wrapped (just like none of the other decorators can be wrapped). Sorry :(

The good news is that we'll likely make providedIn: 'root' the default behavior at some point.

@GregOnNet
Copy link
Author

Hi Alex,

thank you for the quick answer.
According to our direct conversation I hacked a "custom injectable" instrumenting the internal APIs 傻傻defineInjectable and 傻傻inject .

For everyone interested. The example can be found at StackOverflow: https://stackoverflow.com/questions/59671530/abstracting-injectable-with-angular-ivy-does-not-work?answertab=active#tab-top

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: compiler Issues related to `ngc`, Angular's template compiler
Projects
None yet
Development

No branches or pull requests

3 participants