0

I created a lit-element web component that contains an <input type="text">. Actually I just extended LionInput.

import { InputMixin } from '@core/mixin/form/InputMixin';
import { customElement} from '@lion/core';
import { LionInput } from '@lion/input';

@customElement('ds-input')
export class DSInput extends InputMixin(LionInput) {}

Inside app.module of my Angular app I added the schemas property:

schemas: [CUSTOM_ELEMENTS_SCHEMA],

As you can see in the image below, <my-input> is recognised as web component inside my angular reative form enter image description here

The problem is when I try to reach the <input> inside my web component doing this:

<form [formGroup]="myForm">
   <ds-input [formControlName]="'name'"></ds-input> 
</form>


this.myForm = new FormGroup({
  name: new FormControl()
});

I get the error:

 'ERROR Error: No value accessor for form control with name: 'name'

I perfectly understand the reason of the error, but I can't understand how to solve it, how to make Angular reach the <input> inside <ds-input> I don't find much documentation about how to integrate litElement web component inside an Angular app.

1
  • Were you able to make this work? Commented Feb 11, 2023 at 21:38

2 Answers 2

1

Your component probably needs to implement a ControlValueAccessor interface to create a custom form control directive that integrates with Angular forms.

Something like this:

import { Directive, ElementRef, HostListener, Provider, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

export const INPUT_VALUE_ACCESSOR: Provider = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => DsInputDirective),
  multi: true
};

@Directive({
  selector: 'ds-input',
  providers: [INPUT_VALUE_ACCESSOR]
})
export class DsInputDirective implements ControlValueAccessor {
  private _val: any;
  onChange: any = () => {};
  onTouched: any = () => {};

  get value() {
    return this._val;
  }

  set value(value: any) {
    if (!value || value === this._val) return;
    this._val = value;

    this.onChange(this._val);
    this.onTouched();
  }

  constructor(private elRef: ElementRef) {}

  writeValue(value: any): void {
    this.elRef.nativeElement.modelValue = value;
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  @HostListener('model-value-changed', ['$event.detail'])
  listenForValueChange(detail: any) {
    if (detail.isTriggeredByUser) {
      this.value = this.elRef.nativeElement.modelValue;
    }
  }

  @HostListener('blur')
  listenForControlBlur() {
    this.onTouched();
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Error said you don't have any control for the control named "name". So you can try to do it like this

Try this is your html

<form [formGroup]="myForm">
   <ds-input [formControl]="name"></ds-input> 
</form>

And in your typescript:

public formGroup : FormGroup;
public nameFC : FormControl = new FormControl();

this.formGroup = new FormGroup({
    name: this.nameFC
})

1 Comment

Hi, thank you for you answer; but that's not the problem. I already created a formGroup in my component, even I didn't add the code in this post. Anyway now I added also the code of the angular component The problem is that angular can't reach the input field inside the component ds-input

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.