Introduction
Hi Everybody,
I'm struggling with a difficult use case of mixin in Typescript with Angular. (not mixin in SCSS)
I'd like to use mixins to create complex custom form inputs.
Problem
In the example, we have the TextComponent for the basic implementation of our mixins: https://stackblitz.com/edit/angular-ivy-wva4z7?embed=1&file=src/app/inputs/text.component.ts
as you can see, I use 3 mixins in the extends:
- CvaConnectorMixin: ControlValueAccessor logic with some basic inputs
- LengthValidatorMixin: To add inputs concerning the minLength and maxLength for the input
- ErrorStateMatcherMixin: To manage custom ErrorStateMatcher in our input
At the end, we have the Base which is the base class containing the Injector and all ready to use lifecycle of Angular:
https://stackblitz.com/edit/angular-ivy-wva4z7?file=src/app/mixins/base-class-injector.ts
It means, in every mixin I use, I should have access to my Injector and all inputs/outputs/properties written in each of my mixin inside my TextComponent.
In Development environment, it works, but once I go in production, I get the error:
⚠️ NG0203: inject() must be called from an injection context
Does anyone have an idea how to fix that?
This issue is also referenced here: https://github.com/angular/angular/issues/46970
Answer found!
TL;DR
Replace each @Injectable() in each mixin by @Directive.
Explanation
With Ivy, @Injectable() is becoming mandatory to use DI inside our classes, however when the lib/app is built, it removes the decorator. Which is not the case for @Directive.