Coder Social home page Coder Social logo

ngneat / reactive-forms Goto Github PK

View Code? Open in Web Editor NEW
610.0 18.0 55.0 6 MB

(Angular Reactive) Forms with Benefits ๐Ÿ˜‰

Home Page: https://www.netbasal.com

JavaScript 9.45% TypeScript 87.87% HTML 0.80% Shell 0.07% CSS 1.81%
angular forms reactive-forms typed reactive

reactive-forms's People

Contributors

ajsaraujo avatar alexanderfsp avatar andreialecu avatar burgov avatar c0zen avatar caroso1222 avatar chrisguttandin avatar coly010 avatar danzrou avatar dependabot[bot] avatar hypenate avatar itayod avatar kamilsocha91 avatar marioarnt avatar mgred avatar milesheise avatar netanelbasal avatar ntziolis avatar rafaelss95 avatar shajz avatar sharshuv-quotient avatar tehshin avatar undsoft avatar va-stefanek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactive-forms's Issues

Typings error in base example with ProfileControls interface

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Example from Readme.md which using interface with FormGroup types does not work. (It also doesn't work in real world projects)

Expected behavior

It should work without typings problems

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-ivy-ek8nym look at address property

Nested forms

I'm submitting a...


[X] Support request

Current behavior

I'm using this with nested components where each child component is a CVA that has its own FormGroup. Right now I'm doing something like this, which just feels wrong.

    @ViewChild(DetailGeneralComponent) private general!: DetailGeneralComponent

    ngOnInit(): void {
        this.formGroup = this.fb.group({
            general: this.fb.group<IDetailGeneralForm>({
                manager: undefined,
                delegate: undefined,
                linkUrl: undefined,
                linkTitle: undefined
            })
        })

        const id = +this.route.snapshot.params['id']
    }

    ngAfterViewInit(): void {
        this.formGroup.setControl('general', this.general.formGroup)
    }

Expected behavior

Having to fully define the 'general' control here feels wrong since I'm going to just replace it with the actual form group from the child. Is there a better way to be doing this? Because it's now properly typed, it seems like I need to do that.

`disabled$`, `enabled$` and `status$` are typed as `any`

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

In the types exported by this library, disabled$, enabled$ and status$ are typed as any.

FormArray, FormGroup and FormControl all have this problem.

Check out:
https://cdn.jsdelivr.net/npm/@ngneat/[email protected]/lib/formGroup.d.ts

    readonly disabled$: any;
    readonly enabled$: any;
    readonly status$: any;

Expected behavior

They should have the proper type.

ValidatorFn won't compile in strict mode.

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Fails to compile with error: Type 'AbstractControl' is missing the following properties from type 'AbstractControl<IForm, any>': touch$, dirty$, disabled$, enabled$, status$

This seems to be touched on in #26 , #87 , #101 , #65 . However, I am on the latest version and this still happens, even after trying solutions suggested on these tickets.

Apologies if I'm just using incorrect syntax or interfaces, I'm quite new to reactive forms :) .

Expected behavior

Compiles with no issues (which it does with strict mode off).

Minimal reproduction of the problem with instructions

See line 27 of app.component.ts for error. It seems to be compiling on this site regardless of tsconfig, but the error it shows on the line is what is blocking me in any other environment.
https://codesandbox.io/s/brave-silence-40z69?file=/src/app/app.component.ts

Non-strict mode without any errors:
https://codesandbox.io/s/kind-mayer-s0b3s?file=/src/app/app.component.ts

Stackblitz wasn't consistently loading the dependency correctly.

What is the motivation / use case for changing the behavior?

I'm trying to perform cross validation on multiple form inputs as the minimal example shows.

I can, if necessary, do this without ValidatorFn's but working validation within the reactive form would be highly preferable to custom code on form submission.

Environment


Angular version: 12.2.0 for minimal example, 11.2.6 for production code I'm writing.

Browser **unsure if relevant?**:
- [X] Chrome (desktop) version 92

UpdateValueAndValidity emits event when adding validator directive

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

formGroup.valueChanges emit value when setting a validator directive like required because the library call updateValueAndValidity inside setValidators Fn.

Expected behavior

formGroup.valueChanges should not emit when adding a directive like the default angular form behaviour we can add the possibility to pass global options for updateValueAndValidity to avoid breaking changes and for easier adoption for big project.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-ivy-kzr2zk

What is the motivation / use case for changing the behavior?

migrating big entreprise project to use ngneat/reactive-forms with minimal breaking changes .

Environment


Angular version: 11


Browser:
- [x] Chrome (desktop) version XX
- [x] Chrome (Android) version XX
- [x] Chrome (iOS) version XX
- [x] Firefox version XX
- [x] Safari (desktop) version XX
- [x] Safari (iOS) version XX
- [x] IE version XX
- [x] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Required validator on FormControl not working in unit tests when using jest

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When running unit tests in a jest environment they fail when using the required validator on a FormControl because it always returns true even when the value is invalid. Using the FormControl from the @angular/forms package works fine.

This only happens in a jest environment, the actual functionality in a browser or when using jasmine for the unit tests works as expected. I'm sorry if I've raised this bug in the wrong place, it could be a problem with jest or jsdom. I'm going to keep trying to debug and see if I can find out the reason why.

The following issue might be relevant from what I found when searching the closed issues:
#86

Expected behavior

When the FormControl is invalid then it should return false when checking the valid property for unit tests running with jest.

Minimal reproduction of the problem with instructions

I've attached a zip file to this ticket with a sample angular project that shows the tests passing when using jasmine and failing when using jest.

typed-forms.zip

To run the jasmine unit tests that work use this command:
npm run test

To run the jest unit tests that fail use this command:
npm run test:jest

What is the motivation / use case for changing the behavior?

Unit tests pass when using jest and this project.

Environment

Angular version: 11.2.13

Browser:
- [x] TS Jest version 26.5.6 (jsdom 16.5.3)
 
For Tooling issues:
- Node version: v14.9.0
- Platform: Mac

Migration command does not work: Cannot find module '@phenomnomnominal/tsquery'

I'm submitting a...


[ X ] Bug report 

Current behavior

After a successful install the migration command ng g @ngneat/reactive-forms:migrate is not working:

An unhandled exception occurred: Cannot find module '@phenomnomnominal/tsquery'
Require stack:
- /Users/person/app/node_modules/@ngneat/reactive-forms/schematics/migrate/index.js
- /Users/person/app/node_modules/@angular/cli/node_modules/@angular-devkit/schematics/tools/export-ref.js
- /Users/person/app/node_modules/@angular/cli/node_modules/@angular-devkit/schematics/tools/index.js
- /Users/person/app/node_modules/@angular/cli/utilities/json-schema.js
- /Users/person/app/node_modules/@angular/cli/models/command-runner.js
- /Users/person/app/node_modules/@angular/cli/lib/cli/index.js
- /Users/person/.nvm/versions/node/v13.8.0/lib/node_modules/@angular/cli/lib/init.js
- /Users/person/.nvm/versions/node/v13.8.0/lib/node_modules/@angular/cli/bin/ng
See "/private/var/folders/jd/4qd93gyj3c9_18z3_yvy3gl80000gn/T/ng-Z1HDXJ/angular-errors.log" for further details.

The path is tiny bit changed but only in terms of User name and app folder name. I checked most of those paths and they have the appropriate files.

Expected behavior

It should run migration command successfully.

Minimal reproduction of the problem with instructions

Can't offer repo for reproduction at this point but can try if it will be useful.

Environment


Angular version: 11.0.1


For Tooling issues:
- Node version: 13.8.0 (through NVM)
- Platform: Mac

Others:
Part of app contains Angular Element. Could it be relevant?

Pushing FormGroup to a strongly typed FormArray throws a compilation error

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Following compilation error appears when pushing to typed FormArray

Argument of type 'FormGroup<Element, any>' is not assignable to parameter of type 'AbstractControl<Element>'.
  Types of property 'get' are incompatible.
    Type '{ <K1 extends "minimum" | "maximum">(path?: [K1] | undefined): AbstractControl<Element[K1]>; <K1 extends "minimum" | "maximum", K2 extends keyof Element[K1]>(path?: [...] | undefined): AbstractControl<...>; <K1 extends "minimum" | "maximum", K2 extends keyof Element[K1], K3 extends keyof Element[K1][K2]>(path?: [......' is not assignable to type '(path: string | (string | number)[]) => AbstractControl | null'.
      Types of parameters 'path' and 'path' are incompatible.
        Type 'string | (string | number)[]' is not assignable to type '[any] | undefined'.
          Type 'string' is not assignable to type '[any] | undefined'.ts(2345)

Expected behavior

Minimal reproduction of the problem with instructions

Consider following example:

import { Component } from "@angular/core";
import {
  AbstractControl,
  FormArray,
  FormBuilder,
  FormControl,
  FormGroup
} from "@ngneat/reactive-forms";

interface Element {
  minimum: string;
  maximum: string;
}

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  elementsForm: FormArray<Element>;
  constructor(private formBuilder: FormBuilder) {
    this.elementsForm = formBuilder.array([]);
  }

  addElement() {
    const element = this.formBuilder.group<Element>({
      minimum: '',
      maximum: ''
    });
    this.elementsForm.push(element);
  }
}

this.elementsForm.push(element) causes described error.
I applied following fix:
this.elementsForm.push(element as AbstractControl<Element>) since push method accepts AbstractControl, but FormGroup extends NgFormGroup which doesn't accept generic types.

What is the motivation / use case for changing the behavior?

Environment


Angular version: X.Y.Z


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Unable to pass options to updateValueAndValidity when calling setValidators

I'm submitting a...


[x] Regression
[x] Bug report  

Current behavior

With regular Angular forms calling setValidators does not automatically call updateValueAndValidity.
We had to manually call updateValueAndValidity and had the ability to pass options, like {onlySelf: true} to that method.

Expected behavior

My code broke after migrating to this library, since I used to call updateValueAndValidity with additional options.

The setValidators method should therefore be extended by an optional parameter options, which is passed straight into updateValueAndValidity.

I guess the same behavior applies to clearValidators.

Environment


Angular version: 8

Browser:
- [x] Chrome (desktop) version XX
 

Which is the correct package version? 1.6.1 or 1.7.0 or 1.7.1?

My applicaiton package.json shows the following

   `"@ngneat/reactive-forms": "1.7.0",`

but the package with the exposing of the diff() function is labelled 1.6.1

As a result, I cannot upgrade to get the use of the diff() function.

There seems to be an issue with the package versions.

Cheers

Add persist form functionality

It'll be great to add a built-in method to persist the form value to the storage. For example:

const profileForm = new FormGroup<Profile>({
  firstName: new FormControl(''),
  lastName: new FormControl(''),
  skills: new FormArray([]),
  address: new FormGroup({
    street: new FormControl(''),
    city: new FormControl('')
  })
});

profileForm.persist(key, storage);

Where the key is the storage key, and the storage is local or session.

FormGroupDirective rejects FormGroup

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

The typescript compiler rejects the reactive-forms FormGroup type. This error occurs:

ERROR in libs/frontend/change-maker/feature-more/src/lib/change-password/change-password.component.html:13:9 - error TS2322: Type 'FormGroup<ChangePasswordForm, any>' is not assignable to type 'FormGroup'.
  Types of property 'get' are incompatible.
    Type '{ <K1 extends "confirmPassword" | "currentPassword" | "newPassword">(path?: [K1] | undefined): AbstractControl<ChangePasswordForm[K1]>; <K1 extends "confirmPassword" | "currentPassword" | "newPassword", K2 extends keyof ChangePasswordForm[K1]>(path?: [K1, K2] | undefined): AbstractControl<ChangePasswordForm[K1][K2]>; <K1 extends "confirmPassword" | "currentPassword" | "newPassword", K2 extends keyof ChangePasswordForm[K1], K3 extends keyof ChangePasswordForm[K1][K2]>(path?: [K1, K2, K3] | undefined): AbstractControl<ChangePasswordForm[K1][K2][K3]>; (path?: string | undefined): AbstractControl<any>; }' is not assignable to type '(path: string | (string | number)[]) => AbstractControl | null'.
      Types of parameters 'path' and 'path' are incompatible.
        Type 'string | (string | number)[]' is not assignable to type '[any] | undefined'.
          Type 'string' is not assignable to type '[any] | undefined'.

13   <form [formGroup]="form" (submit)="submit()">
           ~~~~~~~~~~~~~~~~~~

  libs/frontend/change-maker/feature-more/src/lib/change-password/change-password.component.ts:21:16
    21   templateUrl: './change-password.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component ChangePasswordComponent.

Expected behavior

There are no type errors.

Minimal reproduction of the problem with instructions

This is the code used. Note that I have strict mode in my tsconfig.json

import { FormControl, FormGroup } from '@ngneat/reactive-forms';

interface ChangePasswordForm {
  currentPassword: string;
  newPassword: string;
  confirmPassword: string;
}

@Component({
  selector: 'cm-more-change-password',
  templateUrl: './change-password.component.html',
  styleUrls: ['./change-password.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChangePasswordComponent extends ComponentStore<State> {
  readonly form = new FormGroup<ChangePasswordForm>(
    {
      currentPassword: new FormControl('', Validators.compose([(ac) => Validators.required(ac)])),
      newPassword: new FormControl(
        '',
        Validators.compose([(ac) => Validators.required(ac), Validators.pattern(Config.regex.password)])
      ),
      confirmPassword: new FormControl(
        '',
        Validators.compose([(ac) => Validators.required(ac), Validators.pattern(Config.regex.password)])
      ),
    },
    { validators: (ac) => ConfirmPasswordValidator.MatchPassword(ac, 'newPassword', 'confirmPassword') }
  );
}

HTML snippet:

<form [formGroup]="form" (submit)="submit()">
    <im-input label="Current Password">
      <ion-icon slot="start" name="lock-closed"></ion-icon>
      <input formControlName="currentPassword" type="password" placeholder="Current Password" />
      <im-error *ngIf="!form.controls.currentPassword.valid && form.controls.currentPassword.touched">
        Please enter your current password.
      </im-error>
    </im-input>
    <im-input label="New Password">
      <ion-icon slot="start" name="lock-closed"></ion-icon>
      <input formControlName="newPassword" type="password" placeholder="New Password" />
      <im-error *ngIf="!form.controls.newPassword.valid && form.controls.newPassword.touched">
        Your password must be minimum 8 characters, contain at least 1 letter, 1 number, and 1 special
        character.
      </im-error>
    </im-input>
    <im-input label="Confirm New Password">
      <ion-icon slot="start" name="lock-closed"></ion-icon>
      <input formControlName="confirmPassword" type="password" placeholder="Confirm New Password" />
      <im-error *ngIf="!form.controls.confirmPassword.valid && form.controls.confirmPassword.touched">
        Your new password must be valid match.
      </im-error>
    </im-input>
    <!-- Implicit button for form when pressing enter button -->
    <button style="display: none;" [disabled]="!form.valid"></button>
  </form>

What is the motivation / use case for changing the behavior?

Environment


Angular version: 9.1.11


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [x] Edge version 84.0.522.48
 
For Tooling issues:
- Node version: XX  12.13
- Platform:  Docker, Windows

Others:

Type FormGroup is not assignable to type AbstractControl

Hi,

in various places I'm getting following error:

Type 'FormGroup<any, any>' is not assignable to type 'AbstractControl'.

It happens for example when I'm using nested FormGroups. The example from the docs also produces this error.

import { FormGroup } from '@ngneat/reactive-forms';

interface Profile {
  firstName: string;
  lastName: string;
  address: {
    street: string;
    city: string;
  };
}

const profileForm = new FormGroup<Profile>({
  firstName: new FormControl(''),
  lastName: new FormControl(''),
  address: new FormGroup({
    street: new FormControl(''),
    city: new FormControl('')
  })
});

Type 'FormGroup<{ street: string; city: string; }, ValidationErrors>' is not assignable to type 'AbstractControl<{ street: string; city: string; }>'.
Types of property 'get' are incompatible.
Type '{ <K1 extends "street" | "city">(path?: [K1] | undefined): AbstractControl<{ street: string; city: string; }[K1]>; <K1 extends "street" | "city", K2 extends keyof { street: string; city: string; }[K1]>(path?: [...] | undefined): AbstractControl<...>; <K1 extends "street" | "city", K2 extends keyof { ...; }[K1], K3 e...' is not assignable to type '(path: string | (string | number)[]) => AbstractControl | null'.
Types of parameters 'path' and 'path' are incompatible.
Type 'string | (string | number)[]' is not assignable to type '[any] | undefined'.
Type 'string' is not assignable to type '[any] | undefined'

How do I get the FormGroup's value, not the ControlsValue

I'm submitting a...

[X] Support request

Current behavior

A FormGroup's value$ observable emits a ControlsValue<T> instead of a T.

Expected behavior

I want to actually get a value of type T so that I can do this:

this.formGroup.value$.pipe(
    takeUntil(this.unsubscribe$),
).subscribe(x => {
    this.onTouch?.()
    this.onModelChange?.(x)
})

That doesn't work though because x there isn't actually of type T

I'm doing nested forms, and so when this form changes, I pass the value up to the parent's control.

Environment

Angular version: 12.1.2


Browser:
- [ X] Chrome (desktop) version XX
 
For Tooling issues:
- Node version: v12.19.0
- Platform:  Windows 10

Imports

@Coly010 @itayod these are the imports we need to support both in eslint and schematics:

Validators,
AbstractControl,
ValidatorFn, AsyncValidatorFn, ControlValueAccessor, Validator

Uninitialized FormControl can generate runtime errors

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[x ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Hello, neat library ;) And looking to be a great time saver

I'm puzzled by the possibility of initializing a FormControl with bad data. Please see the following screenshots:

image

Here, I forgot to initialize the activityName form control with a value.

Later, I feed this form control to a function that requires a string:

image

The compiler doesn't have my back unfortunately, and I get a runtime error!

Expected behavior

I would expect to have as much type safety as possible at compile time.

I'm not familiar with writing generics producing code. But a quick prototype shows me it is possible to add this constraint at the language level.

image

Is this a bug? I can't se a valid use case for the current behavior.

I can see you mark the formState as optional here:

constructor(formState?: OrBoxedValue<T>, validatorOrOpts?: ValidatorOrOpts, asyncValidator?: AsyncValidator) {

If that's really a necessity, I would expect the underlying form control value to return a string | undefined (which would still be annoying be better than getting a runtime error)

Thanks :)

Cannot find diff() function

Hi,
I see the following in the docs

				this.value$.pipe(diff()).subscribe((value) => {
					// value is emitted only if it has been changed, and only the changed parts.
				})

Where is the diff() function imported from? I can't seem to find a module that exports such a function.

Thanks

possible bug using formBuilder

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

controls created using formBuilder do not appear to have all the features that they should

        this.formGroup = this.formBuilder.group({
            categoryKey: null,
            description: null
        });
        
        // does not work
        this.formGroup.controls.categoryKey.errors$.subscribe()

        // works
        const control = new FormControl('');
        control.errors$.subscribe(errors => {});

In this sample shown, using a directly created form control by copy pasting from the docs, the errors$ observable is present. However, trying to access the errors$ on my control created using formBuilder gives me a TS linting error saying it doesn't exist and suggesting the vanilla errors object

Expected behavior

As far as I can tell from the docs, it sounds like controls made with formBuilder should also be fully featured. I checked other items like disabled$ etc and none of them appear on the item made with formBuilder

Minimal reproduction of the problem with instructions

just create something with formBuilder and try to access items like errors$

What is the motivation / use case for changing the behavior?

To fix what appears to be broken behaviour (I apologize if I am just doing something wrong here or misinterpreting how it should work, in which case possibly a clarification added to the docs could help instead?)

Environment


Angular version: 7.2.15
TS version: 3.2.4

Browser:
- [x] Chrome (desktop) version 84
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

FormControl.errorsSubject is undefined when using asyncValidator

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When instantiating a FormGroup with asyncValidators an error occurs.

ERROR TypeError: Cannot read property 'next' of undefined at FormControl.setErrors (ngneat-reactive-forms.js:368) at SafeSubscriber._next (forms.js:3241) at SafeSubscriber.__tryOrUnsub (Subscriber.js:183) at SafeSubscriber.next (Subscriber.js:122) at Subscriber._next (Subscriber.js:72) at Subscriber.next (Subscriber.js:49) at Observable._subscribe (subscribeToArray.js:3) at Observable._trySubscribe (Observable.js:42) at Observable.subscribe (Observable.js:28) at FormControl._runAsyncValidator (forms.js:3236)

Expected behavior

Should work. Does so when using default angular FormBuilder.

Minimal reproduction of the problem with instructions

Created a form group with some sync and some async validators (which are fetching stuff from the API)

Environment


Angular version: 11.2.0


Browser:
- [x] Chrome (desktop) version 91.0.4472.77
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 12.16.1  
- Platform:   Windows

Others:

Fields on FormGroup not updated on patchValue while having enabled/disabledWhile

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

I have a few fields on a FormGroup, and some of them I set an enabledWhile function to enable/disable them based on whether other fields have certain values or not. So far so good. The problem arises when I try to use the FormGroup to edit an existing item and execute a patchValue with all the data needed to update the FormGroup, and then the issues start: the fields that don't have any conditional enabled/disabled state, work just fine, but those that have the enableWith function applied don't get their value update on the UI (despite the FormGroup.value reflecting the values correctly).
I have to execute a setTimeout(this.formData.patchValue(data)) right below the first patchValue to update these neglected fields and reflect the value on the UI.

Expected behavior

I would expect that when I perform a patchValue, that the FormGroup gets correctly updated, even for those fields that have a enabledWhile/disabledWhile method applied.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: 11.0.0


Browser:
- [X] Chrome (desktop) version 87.0.4280.66
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Validators for input type="radio" don't work.

Control is valid when Validators.required is set.

I'm submitting a...


[X] Bug report

Current behavior

Radio control is always valid

Expected behavior

To work same as native FormControl

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-ivy-emnm3t?file=src%2Fapp%2Fapp.component.ts
Switch FormControl between @angular/forms and @ngneat/reactive-forms and look at valid/invalid status.

What is the motivation / use case for changing the behavior?

Validate the radio control

Environment


Angular version: ^11.0.8

Browser:
- [x] Chrome (desktop) version XX
 
For Tooling issues:
- Node version: v14.16.0
- Platform:  Windows

strictTemplate complains about ngNeat Types

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[X] Support request
[ ] Other... Please describe:

Current behavior

I would like to activate the strictTemplate property in tsconfig but it is complaining that the FormGroup<..,..> of ngNeat does not match the FormGroup of angular:

Error: libs/**/**/form.component.ts:37:20 - error TS2322: Type 'FormGroup<MyForm, any>' is not assignable to type 'FormGroup'.
  Types of property 'addControl' are incompatible.
    Type '<K extends keyof MyForm>(name: K, control: AbstractControlsOf<MyForm>[K]) => void' is not assignable to type '(name: string, control: AbstractControl, options?: { emitEvent?: boolean | undefined; } | undefined) => void'.
      Types of parameters 'control' and 'control' are incompatible.
        Type 'AbstractControl' is not assignable to type 'FormControl<string, any> | AbstractControl<string[] | null | undefined, any> | undefined'.
          Type 'AbstractControl' is missing the following properties from type 'AbstractControl<string[] | null | undefined, any>': touch$, dirty$, disabled$, enabled$, status$

37             <form [formGroup]="form">

I could try to cast it into a FormGroup of angular but I am also using the eslint rule to not import it from @angular/reactive-form :s

I know the error is valid but what do you propose ?

FormControl asyncValidator not Correctly Overriden

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Trying to upgrade to Angular 10 and on build I get this error
ERROR in node_modules/@ngneat/reactive-forms/lib/formControl.d.ts:7:14 - error TS2610: 'asyncValidator' is defined as an accessor in class 'FormControl', but is overridden here in 'FormControl<T, E>' as an instance property.

Expected behavior

I would expect it to build without the error above

Minimal reproduction of the problem with instructions

After upgrading to Angular 10, simply try to run the app.

Environment


Angular version: 10.1.0

Others

This was asked in a different issue and I was told it was unrelated so I thought to open up a new issue for any incoming PRs. I have not had the opportunity to dive too deply in this but I am wondering if the asyncValidator needs to be in the FormControl class or if it could just use the inherited property.

Thanks again for your quick response on the original question.

Fails to compile

I'm submitting a...


[X] Bug report  

Current behavior

When I build my project I'm getting compiler errors from the controls in this package. For example, this is the first one that appears:

Error: node_modules/@ngneat/reactive-forms/lib/formControl.d.ts:20:9 - error TS2416: Property 'asyncValidator' in type 'FormControl<T, E>' is not assignable to the same property in base type 'FormControl'.
Type 'AsyncValidatorFn<T, any> | null' is not assignable to type 'AsyncValidatorFn | null'.
Type 'AsyncValidatorFn<T, any>' is not assignable to type 'AsyncValidatorFn'.
Types of parameters 'control' and 'control' are incompatible.
Type 'AbstractControl' is missing the following properties from type 'AbstractControl<T, any>': touch$, dirty$, disabled$, enabled$, status$

20 get asyncValidator(): AsyncValidatorFn | null;

Minimal reproduction of the problem with instructions

example.zip

Environment


Angular version: 11.0.0
For Tooling issues:
- Node version: v15.3.0
- Platform:  mac BigSur 11.1

Others:

I saw the pinned issue, but while similar I think this is different as I'm just simply doing a build with your package included.

V2 - Fully Typed Version [BREAKING_CHANGES]

In the current version, we tried to provide the maximum typing functionality we could get to make the migration as seamless as possible.

In the next version, we want to add the following features:

  • Currently, when using get or getControl we need to infer the control type explicitly:
const profileForm = new FormGroup<Profile>({
  firstName: new FormControl(''),
  lastName: new FormControl(''),
  skills: new FormArray([]),
  address: new FormGroup({
    street: new FormControl(''),
    city: new FormControl('')
  })
});

const cityControl = profileForm.getControl('address', 'city') as FormControl<string>;

We need to use TS to automatically infer the type so that users can write:

const cityControl = profileForm.getControl('address', 'city');
  • Improving Validators' typings. It'll be great to add both the control value and errors type:
type Errors = {
  passwordMismatch: boolean;
}

const form = new FormGroup<ChangePasswordForm, Errors>({
  password: new FormControl(),
  repeatPassword: new FormControl()
}, 
{ validator });

// The signature of validator should automatically be:
function validator(control: FormGroup<ChangePasswordForm>): Errors | null {}

Nested FormBuilder typing issue

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report 
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When I'm trying to use FormBuilder a revive interface assignable error.

image

Expected behavior

FormBuilder should work the same as new FormGroup() and new FormArray() instances.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-ivy-fn2teb

What is the motivation / use case for changing the behavior?

Compatibility to use FormBuilder.

Environment


Angular version: ^10.2.4
"@ngneat/reactive-forms": "^1.5.1"

Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: v15.6.0
- Platform:  Mac

new Control Methods - enable/disable multiple form controls with single method - patchEnable() & patchDisable()

I'm submitting a new approach to maintain state of form controls (disable/enable multiple form controls with single method).


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ x ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Expected behavior

Two new Control Methods patchEnable() & patchDisable(). They base on setEnable(), setDisable() methods where new behavior is possibility to disable list of controls.

Idea behind this methods is base on patchValue() method.

This change would is completely new and behaves different base on form element use:

  1. formControl.ts:
  • patchEnable(), works same as setEnable for code consistency
  • patchDisable(), works same as setDisable for code consistency
  1. formGroup.ts:
  • patchEnable(), inputs object with control names which should be enabled and options
  • patchDisable(), inputs object with control names which should be disabled and options
  1. formArray.ts:
  • patchEnable(), inputs boolean array where true enables control, false disable it
  • patchDisable(), inputs boolean array where false enables control, true disable it

What is the motivation / use case for changing the behavior?

This would give possibility of maintaining form multiple form controls at a time like in already existing method patchValue().

Multiple Validators throwing TypeError

From short initial investigation it seems like this typing:

validators?: ValidatorFn<T, Partial<E>> | ValidatorFn<T, Partial<E>>[] | null;

Needs to be changed to be recursive in such a way that it can aggregate the different Validators that are used on a FormControl

At the moment, an error is thrown for the following:

email: new FormControl('', [Validators.required, Validators.email])

Which states that {email: true} is not assignable to {required: true}.

I believe this needs a slight change to how the object type is built.

FormArray helpers to remove controls.

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Hello,

I'm using the lib and it would be great if there was more methods to remove controls from FormArray

Currently there's only a removeAt(index: number) method (inherited from @angular/forms) which is not very convenient to remove a control by value or by a given predicate.

I am thinking about something like this in the FormArray class:

removeWhen(predicate: (value: T) => boolean) {
  for (let i = 0; i < this.length; ++i) {
    if (predicate(this.at(i).value)) {
      this.removeAt(i);
    }
  }
};

remove(value: T) {
  this.removeWhen((v) => v === value);
};

I can make a PR if you are interested by such a feature ๐Ÿš€

Thanks for your work ๐Ÿ‘

BTW, the link to the repo is outdated on NPM, you should update repo field

FormControllWrapperValueAccessor

Hi, I really like the idea behind this project and especially the touch$ (but would call it touched$ ;-) it's dirty, it's enabled, it's disabled, it's pristine and ** it's touched**, etc so touch is a bit out of place ) feature.
So what I would propose is to add an abstract class like ControlValueAccessor for use with a Control simply wrapping around a FormGroup (AbstractFormControl actually).

Let's say I have the usual Person object. I want to create a ControlValueAccessor that would wrap around the FormGroup. So finally I could use this component as a form component.

It's much easier now with your reactive-forms but would be even better with an abstract FormControllWrapperValueAccessor.

If I'm not clear enough I can elaborate or maybe create a simple proof of concept.

Idea coming from https://timdeschryver.dev/blog/working-with-angular-forms-in-an-enterprise-environment


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Additional data passed through form

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Expected behavior

I would like to propose ability to pass some custom observable data to form to be able to pass it through form control. It is really useful if that data is dependent on something in form model and we want to for example create that form in dedicated service.

  <kendo-multiselect
                #list
                [data]="control.data$ | async"
                [filterable]="true"
                textField="text"
                valueField="value"
                placeholder="T-shirt size"
               [formControl]=[control]
   >
    </kendo-multiselect>

and in service

 createControl(){
   const control = new FormControl<number>(undefined);
   control.passData(someObservableData$);
}

here it is a bit simplified and the use cases is not very visible but imagine this data being dependent on other form values from for example parent form. And some validations and disabled states also also depend on that data in other field etc.

I'm currently working on such form and such feature would be really useful and allow me to do everything much more neatly.

It become really usefull if data is used for a field in model that is in form array and is dependent on field from parent form group.

Just not sure if it should be observable or just "any" and let user decide what is needed.

Saving disabled controls with persist method

Hi everyone!

I'm using the persist method to store the FormGroup to the sessionStorage, but it doesn't store disabled controls (I don't know if there is a reason for that).

Right now, I found a workaround by creating my own class implementing the PersistManager interface but I was wondering if there was any drawbacks to use value$ instead of valueChanges in the line below?
This would allow to integrate the disabled controls when we use the persist method.

Thanks!

Memory Leak

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

I'm investigating some memory bloat in a large form, and noticed that a lot of the form controls are being retained when navigating to/back to the page that contains it, as evidenced by the memory profiler in chrome:

Screenshot 2021-01-21 at 13 34 47

While looking through the code:

private touchChanges = new Subject<boolean>();
private dirtyChanges = new Subject<boolean>();
private errorsSubject = new Subject<Partial<E>>();
readonly touch$ = this.touchChanges.asObservable().pipe(distinctUntilChanged());
readonly dirty$ = this.dirtyChanges.asObservable().pipe(distinctUntilChanged());
readonly value$ = controlValueChanges$<T>(this);
readonly disabled$ = controlDisabled$<T>(this);
readonly enabled$ = controlEnabled$<T>(this);
readonly status$ = controlStatusChanges$<T>(this);
readonly errors$ = controlErrorChanges$<E>(this, this.errorsSubject.asObservable());

It appears that none of these subscriptions or their Subjects are ever completed.

In the case of my form it looks like around 50000 observables are leaked every time I navigate to the specific tab that contains the form.

Note that I'm unsubscribing from the ones that I'm using, but I'm seeing leaks of others I don't use at all, such as errors$

Expected behavior

Subscriptions should be completed somehow.

Minimal reproduction of the problem with instructions

Should be reproducible in any app by default as long as the form is being re-created. Such as wrapping it in an *ngIf. I can't find a working stackblitz or I would've added a repro myself.

What is the motivation / use case for changing the behavior?

Prevents memory leaks.

Environment


Angular version: 11.1.0

touch$ behaviour

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Currently touch$ emits distincted value.

Expected behavior

touch$ should emit value on every touch/untouch control events

What is the motivation / use case for changing the behavior?

New added controls linked to lead control touch$ not receive touch events after first lead control touch event.

Accept observable in mergeValidators/setValidators

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Currently mergeValidators/setValidators doesn't accept observables... we have the validateOn that deals with custom errors, but not with validators.

Expected behavior

I'd expect to see mergeValidators/setValidators accepting observables also, as setValue/patchValue.

What is the motivation / use case for changing the behavior?

I have an use case where I set the validators based on another formControl value, e.g.:

this.formGroup.controls.someControl.setValidators(
  this.formGroup.select(({ dependent }) => dependent).pipe(
    map(dependent => dependent === 'X' ? [Validators.required, Validators.minlength(3)], customValidator),
  ),
);

Also, I think we could add support to accept observable in mergeErrors/setErrors, that would remove the necessity of having validateOn... but that's just an idea.

Environment


Angular version: 10.x.y

Support strict option

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

TypeScript will not compile the project because of the following errors:

Property 'group' in type 'FormBuilder' is not assignable to the same property in base type 'FormBuilder'.
Property 'controls' in type 'FormGroup<T, E>' is not assignable to the same property in base type 'FormGroup'.

Expected behavior

I would expect the project to compile successfully.

Minimal reproduction of the problem with instructions

Please, let me know if a repo with an example project would be helpful. I'm happy to create one if necessary.

What is the motivation / use case for changing the behavior?

I would like to use this library with Angular v10.

Environment


Angular version: 10.0.1


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: v12.18.2
- Platform: MacOS

Others:
- TypeScript: v3.9.5

Error when trying to merge validators

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When invoking mergeValidators an error is thrown.

Expected behavior

The validators are correctly merged without errors.

Minimal reproduction of the problem with instructions

Given a form group created with the typed FormBuilder:

const builder = new FormBuilder();
const group = builder.group<{ title: string }>({
   title: [ '', Validators.required ],
});

when validators are merged

group.mergeValidators(
   (control: NgAbstractControl | AbstractControl<never, never>) => {}
);

then this error is thrown

core.js:6157 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'validate' of null
TypeError: Cannot read property 'validate' of null
    at isValidatorFn (forms.js:754)
    at forms.js:766
    at Array.map (<anonymous>)
    at normalizeValidators (forms.js:765)
    at composeValidators (forms.js:776)
    at coerceToValidator (forms.js:2756)
    at FormGroup.setValidators (forms.js:2951)
    at FormGroup.setValidators (ngneat-reactive-forms.js:510)
    at mergeControlValidators (ngneat-reactive-forms.js:96)
    at FormGroup.mergeValidators (ngneat-reactive-forms.js:481)
    at resolvePromise (zone-evergreen.js:798)
    at resolvePromise (zone-evergreen.js:750)
    at zone-evergreen.js:860
    at ZoneDelegate.invokeTask (zone-evergreen.js:399)
    at Object.onInvokeTask (core.js:28522)
    at ZoneDelegate.invokeTask (zone-evergreen.js:398)
    at Zone.runTask (zone-evergreen.js:167)
    at drainMicroTaskQueue (zone-evergreen.js:569)

Minimal troubleshooting

It seems related to the fact that the group has a null validator. The code that applies a merge doesn't skip it and the following one will use an array like [null, ...]. Therefore, a deeper investigation is needed ๐Ÿ˜„

What is the motivation / use case for changing the behavior?

Environment


Angular version: 11.2.3


Browser:
- [X] Brave Version 1.23.71 Chromium: 90.0.4430.72 (Official Build) (x86_64)
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 14.15.1
- Platform: Mac

Others:

using .setErrors doesn't trigger .errors$ to next()

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Setting an error to a control using .setErrors() does not trigger a new value to be emitted from .errors$.

Expected behavior

calling .setErrors() should trigger .errors$ to emit

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

We're calling .setErrors() based on a response from the API. Currently, this lib only checks for changes in errors directly after valueChanges, but since the API call is async, valueChanges is never triggered.

Environment


Angular version: 9.1.9


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Reactive form testing won't validate the form correctly

I'm submitting a...


[x] Bug report 

Current behavior

When testing a simple component that has a setup form method on init the test for an invalid form fails. The form is valid without having values.
Swapping the ngneat form builder for the Agnualr form builder from angular core it works fine.
The test will output the form's invalid property as true.

Logging the output in the browser works as expected.

Jest is used as a test runner

Expected behavior

The test should output an invalid form after setup.

Minimal reproduction of the problem with instructions

// component
@Component({
  selector: 'user-login',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./login.component.scss'],
  templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
  form;

... 

  constructor(
    private fb: FormBuilder,
  ) {}
  
  ngOnInit(): void {
    this.form = this.createForm();
    // console.log("component", this.form.valid)
    // console.log(this.form)
  }
  
  private createForm() {
    return this.fb.group({
      username: ['', Validators.required],
      password: ['', [Validators.required, Validators.minLength(10)]]
    });
  }
}

// test
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup } from '@ngneat/reactive-forms';

...
beforeEach(waitForAsync(() => {
   ...

    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      imports: [
        ReactiveFormsModule
      ],
      providers: [
        FormBuilder,
        { provide: UserFacade, useValue: userFacade }
      ]
    }).compileComponents();
  }));
  
  beforeEach(async () => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
  });

...
  
  describe('form invalid', () => {
      it('should NOT call userFacade.login', () => {
        component.ngOnInit();
        console.log(component.form.valid)     // ouput is true
      });
...

Environment


Angular version: 10.1.0
ng neat reactive forms version: 1.3.1

Browser:
- [x] Chrome (desktop) version 85.0.4183.102
- [x] Firefox (desktop) version 80.0.1

 
For Tooling issues:
- Node version: 12.18.3
- Platform: Macos

Deep partial update breaks build

I'm submitting a...


[x] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

interface FiltersForm {
  usersSelect: any;
  periodFrom: string;
  periodTo: string;
  dueDateFrom: string;
  dueDateTo: string;
}

 public readonly form: FormGroup<FiltersForm> = this.formBuilder.group<FiltersForm>({
    usersSelect: null,
    periodFrom: '',
    periodTo: '',
    dueDateFrom: '',
    dueDateTo: ''
  });

 this.form.patchValue({ usersSelect: null });

last line breaks build;

ERROR in filters.component.ts:120:7 - err
or TS2769: No overload matches this call.
  Overload 1 of 2, '(valueOrObservable: Observable<DeepPartial<ControlsValue<FiltersForm>>>, options?: Pick<ControlOptions, "onlySelf" | "em
itEvent"> | undefined): Subscription', gave the following error.
    Argument of type '{ usersSelect: null; }' is not assignable to parameter of type 'Observable<DeepPartial<ControlsValue<FiltersForm>>>'.
      Object literal may only specify known properties, and 'usersSelect' does not exist in type 'Observable<DeepPartial<ControlsValue<Filte
rsForm>>>'.
  Overload 2 of 2, '(valueOrObservable: DeepPartial<ControlsValue<FiltersForm>>, options?: Pick<ControlOptions, "onlySelf" | "emitEvent"> |
undefined): void', gave the following error.
    Type 'null' is not assignable to type 'DeepPartial<any> | undefined'.

120       this.form.patchValue({ usersSelect: null });
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

filters.component.ts:28:3
    28   usersSelect: any;
         ~~~~~~~~~~~
    The expected type comes from property 'usersSelect' which is declared here on type 'DeepPartial<ControlsValue<FiltersForm>>'

When change type of usersSelect to usersSelect: number | null; error disappears.

Expected behavior

Deep partials to work with any;
DeepPartial = any;

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: X.Y.Z


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Errors API

  • hasError - typed?
  • getError - typed?
  • errorsChanges$?

Maybe expose something such as:

<div *ngIf="control.hasErrorAndTouched('required')"></div>
<div *ngIf="control.hasErrorAndDirty('required')"></div>

Instead of:

<div *ngIf="control.hasError('required') && control.touched"></div>

The validators are not triggered on value change and init

Context

In one of my project, I performed the migration from Angular 9 to 10.
I saw some failing tests related to the forms validation.
I figured that using this project was the root cause.
Using Angular imports instead (for the FormGroup and FormControl) fixed my issue.

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

The validators are not working (native and custom).

Expected behavior

An empty string value in a control with a required validator or a custom one (actually in this reproduction it was a validator that check if the value is null, undefined or '') should be considered as an error.

Minimal reproduction of the problem with instructions

In this reproduction, there is two identical forms that should invalidate the form right from the initialisation.
One is based on classes from Angular and the second from ngneat.
Angular is working as expected.
Ngneat is telling me that my form is valid.
I can see that the custom validator log is not trigger when the value change in the ngneat form.

https://ngneat-testing-issue.stackblitz.io/
image

What is the motivation / use case for changing the behavior?

It should work like Angular.

Environment


Angular version: 11.0.8


Browser:
- [x] Chrome (desktop) version 89.0.4389.128

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.