Commit 574261d4 authored by Merzough Münker's avatar Merzough Münker
Browse files

fix(forms): introduce the ControlOption coerce

parent 623deef0
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -161,8 +161,9 @@ export class RxapFormArray<T = any,
   *
   * @param index (optional) the index where the control should be created
   * @param state (optional) the initial state of the new control
   * @param options (optional) ControlEventOptions
   */
  public insertAt(index?: number, state?: T): void {
  public insertAt(index?: number, state?: T, options?: ControlEventOptions): void {
    const insertIndex = index ?? this.controls.length;
    const controlOrDefinition = this._builder(state, {
      controlId: insertIndex.toFixed(0),
@@ -180,9 +181,9 @@ export class RxapFormArray<T = any,
    // call the super insert after the update, bc the insert method will
    // trigger a change detection
    if (controlOrDefinition instanceof NgAbstractControl) {
      super.insert(insertIndex, controlOrDefinition);
      super.insert(insertIndex, controlOrDefinition, options);
    } else {
      super.insert(insertIndex, controlOrDefinition.rxapFormGroup!);
      super.insert(insertIndex, controlOrDefinition.rxapFormGroup!, options);
    }
  }

@@ -220,16 +221,32 @@ export class RxapFormArray<T = any,
    markAllPristine(this);
  }

  private coerceValue(value: T[]) {
    for (let index = 0; index < value.length; index++) {
      if (!this.at(index)) {
        this.insertAt(index, value[ index ]);
      }
    }
  }

  public setValue(
    valueOrObservable: T[] | Observable<T[]>,
    options?: ControlEventOptions
  ): Subscription | void {
    if (isObservable(valueOrObservable)) {
      return valueOrObservable.subscribe((value) =>
        super.setValue(value, options)
      return valueOrObservable.subscribe((value) => {
          if (options?.coerce) {
            this.coerceValue(value);
          }
          super.setValue(value, options);
        }
      );
    }

    if (options?.coerce) {
      this.coerceValue(valueOrObservable);
    }

    super.setValue(valueOrObservable, options);
  }

@@ -256,10 +273,17 @@ export class RxapFormArray<T = any,
  ): Subscription | void {
    if (isObservable<T[]>(valueOrObservable)) {
      return valueOrObservable.subscribe((value: T[]) => {
        if (options?.coerce) {
          this.coerceValue(value);
        }
        super.patchValue(value, options);
      });
    }

    if (options?.coerce) {
      this.coerceValue(valueOrObservable);
    }

    super.patchValue(valueOrObservable as T[], options);
  }

@@ -280,22 +304,22 @@ export class RxapFormArray<T = any,
  public setEnable(enable = true, opts?: ControlEventOptions) {
    enableControl(this, enable, opts);
  }
  public push(control: AbstractControl<T>): void {
  public push(control: AbstractControl<T>, options?: ControlEventOptions): void {
    if (isDevMode()) {
      console.warn('It is not recommend to use the FormArray.push method');
    }
    return super.push(control);
    return super.push(control, options);
  }

  public setDisable(disable = true, opts?: ControlEventOptions) {
    disableControl(this, disable, opts);
  }

  public setControl(index: number, control: AbstractControl<T>): void {
  public setControl(index: number, control: AbstractControl<T>, options?: ControlEventOptions): void {
    if (isDevMode()) {
      console.warn('It is not recommend to use the FormArray.setControl method');
    }
    return super.setControl(index, control);
    return super.setControl(index, control, options);
  }

  public markAsTouched(opts?: OnlySelf): void {
+8 −1
Original line number Diff line number Diff line
@@ -33,9 +33,16 @@ export interface ControlOptions {
  emitModelToViewChange?: boolean;
  emitViewToModelChange?: boolean;
  initial?: boolean;
  /**
   * used in the RxapFormArray setValue/patchValue methods.
   *
   * true - if the value/state has not a control with any index. The control is created
   * false - default behavior
   */
  coerce?: boolean;
}

export type ControlEventOptions = Pick<ControlOptions, 'emitEvent' | 'onlySelf'>;
export type ControlEventOptions = Pick<ControlOptions, 'emitEvent' | 'onlySelf' | 'coerce'>;
export type OnlySelf = Pick<ControlOptions, 'onlySelf'>;
export type EmitEvent = Pick<ControlOptions, 'emitEvent'>;
export type ControlPath = Array<string | number> | string;