### File

`src/lib/directives/form.directive.ts`

### Extends

`FormGroupDirective`

### Implements

`OnInit` `OnChanges` `OnDestroy`

### Metadata

Providers

`{ provide: ControlContainer, useExisting: forwardRef(() => FormDirective), } { provide: RXAP_FORM_SUBMIT_METHOD, useValue: null, } { provide: RXAP_FORM_LOAD_METHOD, useValue: null, } { provide: RXAP_FORM_LOAD_FAILED_METHOD, useValue: null, } { provide: RXAP_FORM_LOAD_SUCCESSFUL_METHOD, useValue: null, } { provide: RXAP_FORM_SUBMIT_FAILED_METHOD, useValue: null, } { provide: RXAP_FORM_SUBMIT_SUCCESSFUL_METHOD, useValue: null, } { provide: RXAP_FORM_DEFINITION_BUILDER, useValue: null, }`

Selector | `form[rxapForm]:not([formGroup]):not([ngForm]),rxap-form,form[rxapForm]`
Standalone | `true`
exportAs | `rxapForm`

### Index

###### Properties

- Protected _formDefinition
- Public Readonly cdr
- Public Readonly context
- Public form
- Public Readonly initial
- Public Readonly loaded$
- Public Readonly loading$
- Public Readonly loadingError$
- Public Readonly submitError$
- Public Readonly submitting$

###### Methods

- Protected getSubmitValue
- Protected loadFailed
- Protected loadInitialState
- Protected loadSuccessful
- Public onSubmit
- Protected submit
- Protected submitFailed
- Protected submitSuccessful

###### Inputs

- loadFailedMethod
- loadMethod
- loadSuccessfulMethod
- rxapForm
- submitFailedMethod
- submitMethod
- submitSuccessfulMethod

###### Outputs

- invalidSubmit
- rxapSubmit
- submitSuccessful

###### HostBindings

- class.rxap-loaded
- class.rxap-loading
- class.rxap-loading-error
- class.rxap-submit-error
- class.rxap-submitting

###### Accessors

- submitting
- submitError
- loading
- loaded
- loadingError
- useFormDefinition
- formDefinition

### Constructor

`constructor(cdr: ChangeDetectorRef, formDefinition: FormDefinition | null, submitMethod: FormSubmitMethod<any> | null, loadMethod: FormLoadMethod | null, loadFailedMethod: FormLoadFailedMethod | null, loadSuccessfulMethod: FormLoadSuccessfulMethod | null, submitFailedMethod: FormSubmitFailedMethod | null, submitSuccessfulMethod: FormSubmitSuccessfulMethod | null, formDefinitionBuilder: RxapFormBuilder | null, loadingIndicatorService: LoadingIndicatorService | null, context, initial: T | null)`

Defined in src/lib/directives/form.directive.ts:207

Parameters :

Name | Type | Optional
cdr | `ChangeDetectorRef` | No
formDefinition | `FormDefinition | null` | No
submitMethod | `FormSubmitMethod<any> | null` | No
loadMethod | `FormLoadMethod | null` | No
loadFailedMethod | `FormLoadFailedMethod | null` | No
loadSuccessfulMethod | `FormLoadSuccessfulMethod | null` | No
submitFailedMethod | `FormSubmitFailedMethod | null` | No
submitSuccessfulMethod | `FormSubmitSuccessfulMethod | null` | No
formDefinitionBuilder | `RxapFormBuilder | null` | No
loadingIndicatorService | `LoadingIndicatorService | null` | No
context |  | No
initial | `T | null` | No

### Inputs

loadFailedMethod
Type : `FormLoadFailedMethod | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:196

loadMethod
Type : `FormLoadMethod | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:193

loadSuccessfulMethod
Type : `FormLoadSuccessfulMethod | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:199

rxapForm
Type : `FormDefinition | string`
Defined in src/lib/directives/form.directive.ts:170

submitFailedMethod
Type : `FormSubmitFailedMethod | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:202

submitMethod
Type : `FormSubmitMethod<any> | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:190

submitSuccessfulMethod
Type : `FormSubmitSuccessfulMethod | null`
Default value : `null`
Defined in src/lib/directives/form.directive.ts:205

### Outputs

invalidSubmit
Type : `EventEmitter`
Defined in src/lib/directives/form.directive.ts:138

rxapSubmit
Type : `EventEmitter`
Defined in src/lib/directives/form.directive.ts:135
Emits when the submit method is executed without errors. The result of the submit method is passed as event object. If no submit method is defined then emit after the submit button is clicked.

submitSuccessful
Type : `EventEmitter`
Defined in src/lib/directives/form.directive.ts:142

### HostBindings

class.rxap-loaded
Type : `boolean`
Defined in src/lib/directives/form.directive.ts:160

class.rxap-loading
Type : `boolean`
Defined in src/lib/directives/form.directive.ts:155

class.rxap-loading-error
Type : `Error | null`
Defined in src/lib/directives/form.directive.ts:165

class.rxap-submit-error
Type : `Error | null`
Defined in src/lib/directives/form.directive.ts:150

class.rxap-submitting
Type : `boolean`
Defined in src/lib/directives/form.directive.ts:145

### Methods

Protected getSubmitValue
`getSubmitValue()`
Defined in src/lib/directives/form.directive.ts:491
Returns : `T`

Protected loadFailed
`loadFailed(error: Error)`
Defined in src/lib/directives/form.directive.ts:481

Parameters :

Name | Type | Optional
error | `Error` | No

Returns : `void`

Protected loadInitialState
`loadInitialState(form: RxapFormGroup)`
Defined in src/lib/directives/form.directive.ts:420

Parameters :

Name | Type | Optional
form | `RxapFormGroup` | No

Returns : `void`

Protected loadSuccessful
`loadSuccessful(value: any)`
Defined in src/lib/directives/form.directive.ts:471

Parameters :

Name | Type | Optional
value | `any` | No

Returns : `void`

Public onSubmit
`onSubmit($event: Event)`
Defined in src/lib/directives/form.directive.ts:338

Parameters :

Name | Type | Optional
$event | `Event` | No

Returns : `boolean`

Protected submit
`submit()`
Defined in src/lib/directives/form.directive.ts:505
Returns : `void`

Protected submitFailed
`submitFailed(error: Error)`
Defined in src/lib/directives/form.directive.ts:551

Parameters :

Name | Type | Optional
error | `Error` | No

Returns : `void`

Protected submitSuccessful
`submitSuccessful(value: any)`
Defined in src/lib/directives/form.directive.ts:564

Parameters :

Name | Type | Optional
value | `any` | No

Returns : `void`

### Properties

Protected _formDefinition
Type : `FormDefinition<T>`
Defined in src/lib/directives/form.directive.ts:187

Public Readonly cdr
Type : `ChangeDetectorRef`
Decorators : `@Inject(ChangeDetectorRef)`
Defined in src/lib/directives/form.directive.ts:210

Public Readonly context
Default value : `model<unknown | null>(null)`
Defined in src/lib/directives/form.directive.ts:125

Public form
Type : `RxapFormGroup<T>`
Defined in src/lib/directives/form.directive.ts:121

Public Readonly initial
Default value : `model<T | null>(null)`
Defined in src/lib/directives/form.directive.ts:123

Public Readonly loaded$
Default value : `new ToggleSubject()`
Defined in src/lib/directives/form.directive.ts:184

Public Readonly loading$
Default value : `new ToggleSubject()`
Defined in src/lib/directives/form.directive.ts:183

Public Readonly loadingError$
Default value : `new BehaviorSubject<Error | null>(null)`
Defined in src/lib/directives/form.directive.ts:185

Public Readonly submitError$
Default value : `new BehaviorSubject<Error | null>(null)`
Defined in src/lib/directives/form.directive.ts:182

Public Readonly submitting$
Default value : `new ToggleSubject()`
Defined in src/lib/directives/form.directive.ts:181

### Accessors

submitting
get `submitting()`
Defined in src/lib/directives/form.directive.ts:145

submitError
get `submitError()`
Defined in src/lib/directives/form.directive.ts:150

loading
get `loading()`
Defined in src/lib/directives/form.directive.ts:155

loaded
get `loaded()`
Defined in src/lib/directives/form.directive.ts:160

loadingError
get `loadingError()`
Defined in src/lib/directives/form.directive.ts:165

useFormDefinition
set `useFormDefinition(value: FormDefinition<T> | string)`
Defined in src/lib/directives/form.directive.ts:170

Parameters :

Name | Type | Optional
value | `FormDefinition<T> | string` | No

Returns : `void`

formDefinition
get `formDefinition()`
Defined in src/lib/directives/form.directive.ts:177

    import {
      ChangeDetectorRef,
      Directive,
      EventEmitter,
      forwardRef,
      HostBinding,
      Inject,
      input,
      Input,
      isDevMode,
      model,
      OnChanges,
      OnDestroy,
      OnInit,
      Optional,
      Output,
      SimpleChanges,
      SkipSelf,
    } from '@angular/core';
    import {
      ControlContainer,
      FormGroupDirective,
    } from '@angular/forms';
    import { ToggleSubject } from '@rxap/rxjs';
    import { LoadingIndicatorService } from '@rxap/services';
    import {
      clone,
      isObject,
      isPromise,
    } from '@rxap/utilities';
    import {
      BehaviorSubject,
      Subscription,
    } from 'rxjs';
    import {
      debounceTime,
      filter,
      tap,
    } from 'rxjs/operators';
    import { RxapFormBuilder } from '../form-builder';
    import { RxapFormGroup } from '../form-group';
    import { FormDefinition } from '../model';
    import {
      RXAP_FORM_CONTEXT,
      RXAP_FORM_INITIAL_STATE,
    } from '../tokens';
    import {
      FormLoadFailedMethod,
      FormLoadMethod,
      FormLoadSuccessfulMethod,
      FormSubmitFailedMethod,
      FormSubmitMethod,
      FormSubmitSuccessfulMethod,
    } from './models';
    import {
      RXAP_FORM_DEFINITION,
      RXAP_FORM_DEFINITION_BUILDER,
      RXAP_FORM_LOAD_FAILED_METHOD,
      RXAP_FORM_LOAD_METHOD,
      RXAP_FORM_LOAD_SUCCESSFUL_METHOD,
      RXAP_FORM_SUBMIT_FAILED_METHOD,
      RXAP_FORM_SUBMIT_METHOD,
      RXAP_FORM_SUBMIT_SUCCESSFUL_METHOD,
    } from './tokens';

    @Directive({
      selector: 'form[rxapForm]:not([formGroup]):not([ngForm]),rxap-form,form[rxapForm]',
      providers: [
        {
          provide: ControlContainer,
          // ignore coverage
          useExisting: forwardRef(() => FormDirective),
        },
        // region form provider clear
        // form provider that are directly associated with the current form
        // are cleared to prevent that inner forms can access this providers
        // Example: The parent form has a submit method provider and the inner should
        // not have a submit method provider. If the parent submit method provider is
        // not cleared then the inner form uses the parent submit method provider on
        // submit
        {
          provide: RXAP_FORM_SUBMIT_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_LOAD_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_LOAD_FAILED_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_LOAD_SUCCESSFUL_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_SUBMIT_FAILED_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_SUBMIT_SUCCESSFUL_METHOD,
          useValue: null,
        },
        {
          provide: RXAP_FORM_DEFINITION_BUILDER,
          useValue: null,
        },
        // endregion
      ],

      host: { '(reset)': 'onReset()' },
      // eslint-disable-next-line @angular-eslint/no-outputs-metadata-property
      outputs: [ 'ngSubmit' ],
      exportAs: 'rxapForm',
      standalone: true,
    })
    export class FormDirective<T = any>
      extends FormGroupDirective
      implements OnInit, OnChanges, OnDestroy {
      public override form!: RxapFormGroup<T>;

      public readonly initial = model<T | null>(null);

      public readonly context = model<unknown | null>(null);

      /**
       * Emits when the submit method is executed without errors. The result of the
       * submit method is passed as event object.
       *
       * If no submit method is defined then emit after the submit button
       * is clicked.
       */
      @Output()
      public rxapSubmit = new EventEmitter();

      @Output()
      public invalidSubmit = new EventEmitter<Record<string, any>>();

      // eslint-disable-next-line @angular-eslint/no-output-rename
      @Output('submitSuccessful')
      public submitSuccessful$ = new EventEmitter();

      @HostBinding('class.rxap-submitting')
      public get submitting(): boolean {
        return this.submitting$.value;
      }

      @HostBinding('class.rxap-submit-error')
      public get submitError(): Error | null {
        return this.submitError$.value;
      }

      @HostBinding('class.rxap-loading')
      public get loading(): boolean {
        return this.loading$.value;
      }

      @HostBinding('class.rxap-loaded')
      public get loaded(): boolean {
        return this.loaded$.value;
      }

      @HostBinding('class.rxap-loading-error')
      public get loadingError(): Error | null {
        return this.loadingError$.value;
      }

      @Input('rxapForm')
      public set useFormDefinition(value: FormDefinition<T> | '') {
        if (value) {
          this._formDefinition = value as any;
          this.form = value.rxapFormGroup;
        }
      }

      public get formDefinition(): FormDefinition<T> {
        return this._formDefinition;
      }

      public readonly submitting$ = new ToggleSubject();
      public readonly submitError$ = new BehaviorSubject<Error | null>(null);
      public readonly loading$ = new ToggleSubject();
      public readonly loaded$ = new ToggleSubject();
      public readonly loadingError$ = new BehaviorSubject<Error | null>(null);

      protected _formDefinition!: FormDefinition<T>;

      @Input()
      public submitMethod: FormSubmitMethod<any> | null = null;

      @Input()
      public loadMethod: FormLoadMethod | null = null;

      @Input()
      public loadFailedMethod: FormLoadFailedMethod | null = null;

      @Input()
      public loadSuccessfulMethod: FormLoadSuccessfulMethod | null = null;

      @Input()
      public submitFailedMethod: FormSubmitFailedMethod | null = null;

      @Input()
      public submitSuccessfulMethod: FormSubmitSuccessfulMethod | null = null;

      private _autoSubmitSubscription = new Subscription();

      constructor(
        @Inject(ChangeDetectorRef) public readonly cdr: ChangeDetectorRef,
        @Optional()
        @Inject(RXAP_FORM_DEFINITION)
        formDefinition: FormDefinition | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_SUBMIT_METHOD)
        submitMethod: FormSubmitMethod<any> | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_LOAD_METHOD)
        loadMethod: FormLoadMethod | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_LOAD_FAILED_METHOD)
        loadFailedMethod: FormLoadFailedMethod | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_LOAD_SUCCESSFUL_METHOD)
        loadSuccessfulMethod: FormLoadSuccessfulMethod | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_SUBMIT_FAILED_METHOD)
        submitFailedMethod: FormSubmitFailedMethod | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_SUBMIT_SUCCESSFUL_METHOD)
        submitSuccessfulMethod: FormSubmitSuccessfulMethod | null = null,
        // skip self, bc the token is set to null
        @SkipSelf()
        @Optional()
        @Inject(RXAP_FORM_DEFINITION_BUILDER)
        protected readonly formDefinitionBuilder: RxapFormBuilder | null = null,
        @Optional()
        @Inject(LoadingIndicatorService)
        protected readonly loadingIndicatorService: LoadingIndicatorService | null = null,
        @Optional()
        @Inject(RXAP_FORM_CONTEXT)
        context: unknown = null,
        @Optional()
        @Inject(RXAP_FORM_INITIAL_STATE)
        initial: T | null = null,
      ) {
        super([], []);
        this.submitMethod = submitMethod ?? this.submitMethod;
        this.loadMethod = loadMethod ?? this.loadMethod;
        this.loadFailedMethod = loadFailedMethod ?? this.loadFailedMethod;
        this.loadSuccessfulMethod = loadSuccessfulMethod ?? this.loadSuccessfulMethod;
        this.submitFailedMethod = submitFailedMethod ?? this.submitFailedMethod;
        this.submitSuccessfulMethod = submitSuccessfulMethod ?? this.submitSuccessfulMethod;
        if (!formDefinition && formDefinitionBuilder) {
          formDefinition = formDefinitionBuilder.build<FormDefinition>();
        }
        if (formDefinition) {
          this._formDefinition = formDefinition;
          this.form = formDefinition.rxapFormGroup;
        }
        this.loadingIndicatorService?.attachLoading(this.loading$);
        this.loadingIndicatorService?.attachLoading(this.submitting$);
        if (context) {
          this.context.set(context);
        }
        if (initial && typeof initial === 'object' && !Array.isArray(initial)) {
          this.initial.set(initial);
        }
      }

      public override ngOnChanges(changes: SimpleChanges) {
        super.ngOnChanges(changes);

        const formChange = changes['form'];

        if (formChange && !formChange.firstChange) {
          this.loadInitialState(formChange.currentValue);
        }
      }

      public ngOnInit() {
        if (!this._formDefinition) {
          // TODO : replace with rxap error
          throw new Error('The form definition instance is not defined');
        }
        if (!this.form) {
          // TODO : replace with rxap error
          throw new Error('The form instance is not defined');
        }
        this.loadInitialState(this.form);

        function HasNgOnInitMethod(obj: any): obj is OnInit {
          return obj && typeof obj.ngOnInit === 'function';
        }

        if (HasNgOnInitMethod(this._formDefinition)) {
          this._formDefinition.ngOnInit();
        }

        if (this._formDefinition.rxapMetadata.autoSubmit) {
          const debounce =
            typeof this._formDefinition.rxapMetadata.autoSubmit === 'number'
              ? this._formDefinition.rxapMetadata.autoSubmit
              : 5000;
          this._autoSubmitSubscription = this
            .form
            .valueChanges
            .pipe(
              debounceTime(debounce),
              filter(() => this.form.valid),
              tap((value) => {
                  if (isDevMode()) {
                    console.debug(
                      `Auto submit form '${ this._formDefinition.rxapMetadata.id }'`,
                      value,
                    );
                  }
                },
              ),
              tap(() => this.submit()),
            )
            .subscribe();
        }
      }

      public override onSubmit($event: Event): boolean {
        $event.preventDefault();
        super.onSubmit($event);
        if (this.form.valid) {
          this.submit();
        } else {

          // eslint-disable-next-line no-inner-declarations
          function reduceErrors(control: any, errors: Record<string, any> = {}): Record<string, any> {

            if (control.invalid) {
              if (control.controls) {
                if (Array.isArray(control.controls)) {
                  const errorList = [];
                  for (const item of control.controls) {
                    errorList.push(reduceErrors(item));
                  }
                  errors[control.controlId] = errorList;
                } else {
                  const innerErrors = {};
                  for (const child of Object.values(control.controls)) {
                    reduceErrors(child, innerErrors);
                  }
                  errors[control.controlId] = innerErrors;
                }
              } else {
                if (control.errors) {
                  errors[control.controlId] = control.errors;
                }
              }
            }

            return errors;
          }

          if (isDevMode()) {
            console.log(
              'Form submit is not valid for: ' + this.form.controlId,
              this.form.errors,
            );

            // eslint-disable-next-line no-inner-declarations
            function printErrorControls(control: any) {
              if (!control.valid) {
                console.group(control.controlId);
                if (control.controls) {
                  if (Array.isArray(control.controls)) {
                    for (let i = 0; i < control.controls.length; i++) {
                      const child = control.controls[i];
                      if (!child.valid) {
                        console.group(`index: ${ i }`);
                        printErrorControls(child);
                        console.groupEnd();
                      }
                    }
                  } else {
                    for (const child of Object.values(control.controls)) {
                      printErrorControls(child);
                    }
                  }
                } else {
                  if (control.errors) {
                    for (const [ key, value ] of Object.entries(control.errors)) {
                      console.group(key);
                      console.log(value);
                      console.groupEnd();
                    }
                  }
                  console.log('value: ', control.value);
                }
                console.groupEnd();
              }
            }

            printErrorControls(this.form);
          }
          this.invalidSubmit.emit(reduceErrors(this.form));
        }

        return false;
      }

      protected loadInitialState(form: RxapFormGroup): void {
        const initial = this.initial();
        if (initial && typeof initial === 'object' && !Array.isArray(initial)) {
          if (isDevMode()) {
            console.log('use the value from input initial');
          }
          form.patchValue(initial);
        } else {
          if (this.loadMethod) {
            this.loading$.enable();

            try {
              const resultOrPromise = this.loadMethod.call({ context: this.context(), initial: this.initial() });
              if (isPromise(resultOrPromise)) {
                resultOrPromise
                  .then((value) => {
                    form.patchValue(value);
                    this.loaded$.enable();
                    this.loadSuccessful(value);
                  })
                  .catch((error) => {
                    this.loadingError$.next(error);
                    this.loadFailed(error);
                  })
                  .finally(() => {
                    this.loading$.disable();
                    this.cdr.detectChanges();
                  });
              } else if (isObject(resultOrPromise)) {
                form.patchValue(resultOrPromise);
                this.loaded$.enable();
                this.loadSuccessful(resultOrPromise);
                this.loading$.disable();
              }
            } catch (error: any) {
              this.loaded$.disable();
              this.loadingError$.next(error);
              this.loadFailed(error);
              this.loading$.disable();
            }
          } else {
            if (isDevMode()) {
              console.warn(
                'The form loading method is not defined for: ' + this.form.controlId,
              );
            }
            this.loaded$.enable();
          }
        }
      }

      protected loadSuccessful(value: any) {
        if (this.loadSuccessfulMethod) {
          this.loadSuccessfulMethod.call(value);
        } else if (isDevMode()) {
          console.warn(
            'The load successful is not defined for: ' + this.form.controlId,
          );
        }
      }

      protected loadFailed(error: Error) {
        console.debug('Load Error:', error);
        console.error('Load Error:', error.message);
        if (this.loadFailedMethod) {
          this.loadFailedMethod?.call(error);
        } else if (isDevMode()) {
          console.warn('The form loading failed for: ' + this.form.controlId);
        }
      }

      protected getSubmitValue(): T {
        let value: T = undefined as any;

        if (typeof this._formDefinition['getSubmitValue'] === 'function') {
          value = this._formDefinition.getSubmitValue();
        } else if (typeof this._formDefinition['toJSON'] === 'function') {
          value = this._formDefinition.toJSON();
        }

        value = value ?? clone(this.form.value);

        return value;
      }

      protected submit() {
        const value = this.getSubmitValue();
        if (this.submitMethod) {
          Reflect.set(this, 'submitted', false);
          this.submitting$.enable();
          this.submitError$.next(null);
          try {
            const resultOrPromise = this.submitMethod.call(value, this.context(), this.initial());
            if (isPromise(resultOrPromise)) {
              resultOrPromise
                .then((result) => {
                  Reflect.set(this, 'submitted', true);
                  this.rxapSubmit.emit(result);
                  this.submitSuccessful(result);
                })
                .catch((error) => {
                  this.submitError$.next(error);
                  this.submitFailed(error);
                })
                .finally(() => {
                  this.submitting$.disable();
                  this.cdr.detectChanges();
                });
            } else {
              Reflect.set(this, 'submitted', true);
              this.rxapSubmit.emit(resultOrPromise);
              this.submitSuccessful(resultOrPromise);
              this.submitting$.disable();
            }
          } catch (error: any) {
            this.submitting$.disable();
            this.submitError$.next(error);
            this.submitFailed(error);
          }
        } else {
          if (isDevMode()) {
            console.warn(
              'The form submit method is not defined for: ' + this.form.controlId,
            );
          }

          this.rxapSubmit.emit(value);
          this.submitSuccessful(value);
        }
      }

      protected submitFailed(error: Error) {
        console.debug('Submit Error:', error);
        console.error('Submit Error:', error.message);
        if (this.submitFailedMethod) {
          this.submitFailedMethod.call(error);
        } else if (isDevMode()) {
          console.warn(
            'The form submit failed method is not defined for: ' +
            this.form.controlId,
          );
        }
      }

      protected submitSuccessful(value: any) {
        this.submitSuccessful$.next(value);
        if (this.submitSuccessfulMethod) {
          this.submitSuccessfulMethod.call(value);
        } else if (isDevMode()) {
          console.warn(
            'The form submit successful method is not defined for: ' +
            this.form.controlId,
          );
        }
      }

      public override ngOnDestroy() {
        super.ngOnDestroy();
        this._autoSubmitSubscription?.unsubscribe();

        function HasNgOnDestroyMethod(obj: any): obj is OnDestroy {
          return obj && typeof obj.ngOnDestroy === 'function';
        }

        if (HasNgOnDestroyMethod(this._formDefinition)) {
          this._formDefinition.ngOnDestroy();
        }

      }
    }

# results matching ""

# No results matching ""