0

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.

1 Answer 1

0

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);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.