Reputation: 198
Is there a way to extend a component which is exported by a 3rd party library in such a way that I can intercept and change the value of a specific Input?An important mention is that the component already implements the `ngOnChanges` hook so, if I create a directive which targets the component, the directive's `ngOnChanges` hook is executed AFTER the component one.
If there is no other way to extend it and keep the original component selector, I'm OK to extend the parent component Class with a new selector, like:
@Component({
selector: 'extended-component',
template: '',
})
export class YourExtendedComponent extends ThirdPartyComponent implements OnChanges {
@Input() adjustedInputValue: string;
ngOnChanges(changes: SimpleChanges): void {
// Check if the inputValue has changed
if (changes.inputValue) {
// Your logic to adjust the input value goes here
this.adjustedInputValue = this.adjustInput(changes.inputValue.currentValue);
}
}
private adjustInput(value: string): string {
// Your custom logic to adjust the input value
return value.toUpperCase(); // Example: Convert to uppercase
}
}
The problem is that my ThirdPartyComponent has some component Providers:
@Component({
selector: 'some-component',
standalone: true,
template: '',
providers: [
SomeInjectable,
AnotherInjectable
],
encapsulation: ViewEncapsulation.None
})
Would I end up with duplicate instances for SomeInjectable
?
As I said, ideally I would try to achieve this without changing the initial compoennt selector.
Upvotes: 0
Views: 50
Reputation: 804
No, when you extend a component A with another component B, the decorator Component
of component B won't be taken into account (its imports as well). So, no worries.
Here you have an example stackblitz that shows this case. You will see this error in the console:
ERROR
Error: R3InjectorError(Environment Injector)[SomeInjectable -> SomeInjectable]:
NullInjectorError: No provider for SomeInjectable!
The code:
import {
Component,
inject,
Injectable,
ViewEncapsulation,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
@Injectable()
class SomeInjectable {
constructor() {
console.log('SomeInjectable->constructor');
}
}
@Component({
selector: 'some-component',
standalone: true,
template: `some-component {{name}}`,
providers: [SomeInjectable],
encapsulation: ViewEncapsulation.None,
})
export class SomeComponent {
name = 'Angular';
}
@Component({
selector: 'new-component',
standalone: true,
template: `new-component {{name}}`,
providers: [
/* SomeInjectable */
],
})
export class NewComponent extends SomeComponent {
someInjectable = inject(SomeInjectable);
override name = 'Angular 2';
}
@Component({
selector: 'app-root',
standalone: true,
template: `
<h1>Hello from {{ name }}!</h1>
<new-component></new-component>
`,
imports: [NewComponent],
})
export class App {
name = 'Angular';
}
bootstrapApplication(App);
Upvotes: 0