Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error is not updated when FormArrayState has empty array value #37

Closed
icepeng opened this issue Jan 23, 2018 · 13 comments
Closed

Error is not updated when FormArrayState has empty array value #37

icepeng opened this issue Jan 23, 2018 · 13 comments

Comments

@icepeng
Copy link
Contributor

icepeng commented Jan 23, 2018

When FormArrayState has [] value, error is not updated with SetErrorsAction() or setErrors().

This is necessary because there are use-case of "Array must have one or more value".

If this issue is resolved, validate(required) would be extended to validate FormArrayState.

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 23, 2018 via email

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 27, 2018

@icepeng I was missing some test cases for this, but otherwise setting errors on empty array state works just fine. Are you still encountering this issue? If so, could you provide some example code for it?

@icepeng
Copy link
Contributor Author

icepeng commented Jan 27, 2018

@MrWolfZ This issue still appears for me. I will update minimal reproduction code tomorrow. Thank you.

@icepeng
Copy link
Contributor Author

icepeng commented Jan 30, 2018

https://github.com/icepeng/ngrx-forms-issue
Created repo. There are two type of errors: when item.length > 5, or item.length === 0.
Too many items error is generated properly, but no item error is not generated.

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 30, 2018

Thanks for the reproduction. It helped me find the issue. The problem here is that the array state is defined to be enabled if any of its children is enabled. That means an array without children is always disabled. That in turn causes the error to be ignored since disabled controls cannot have errors set. The same goes for empty groups.

The obvious fix is to invert the condition, but I'll have a good long think about this one before I decide this. I'll update this thread once I've made a decision on how to handle this issue.

Also, the reason why my tests didn't show the issue is that there is an inconsistency between how an initial state is created and how a state is recomputed after a change. I'll fix this as well.

@icepeng
Copy link
Contributor Author

icepeng commented Jan 31, 2018

Great. Could there be a workaround to make my project work before you make a decision?

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 31, 2018

Sure, sorry for not mentioning one. I assume your array is part of a larger group state like in your reproduction, right? In that case I would simply put the error on the containing group. This is of course a bit ugly and might not work if you have your form state split over multiple templates.

So in your reproduction repo you could use this code:

const atLeastOneItem = (myForm: MyForm) => {
  if (myForm.items.length > 0) {
    return {};
  }

  return {
    noItem: true,
  };
};

const atMostFiveItems = (myForm: MyForm) => {
  if (myForm.items.length <= 5) {
    return {};
  }

  return {
    tooMany: myForm.items.length,
  };
};

const validationFormGroupReducer = (state: FormGroupState<MyForm>, action: Action) => {
  state = formGroupReducer(state, action);
  state = validate([atLeastOneItem, atMostFiveItems], state);
  return updateGroup(state, {
    value: validate(required),
  });
};

However, I am already working on the proper fix. I will invert the condition for the isDisabled check. While this is a breaking API change it only affects the edge cases of empty groups or arrays. And as in your case here it should definitely be possible to validate the group/array in such cases.

@icepeng
Copy link
Contributor Author

icepeng commented Jan 31, 2018

In my case, there is child component used like <items-form [itemState]="formState.controls.items"></items-form>. Because there are several type of forms that share items form. Moving error to each parent group would solve the problem, but it would produce a lot of duplication in code base.

Since it is not critical for me right now, I decided to wait until this issue is resolved. Not just waiting for your contribution, I am looking into repo deeper to find out how I can help this project. I found out that required, minLength, maxLength validators would work well with array. How do you think about it?

ps. Thank you for detailed reply!

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 31, 2018

You are right, those validation functions could easily be extended to apply to arrays as well. Since I am already working on the library right now I could add those cases. Or would you like to contribute a PR for this?

@icepeng
Copy link
Contributor Author

icepeng commented Jan 31, 2018

I have no experience contributing a PR, except for fixing some docs.

It would be nice if I can send my first PR for this library, but I am worried about my lack of experience. I will ready for PR in this week. Then, please point out my mistakes.

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 31, 2018

Everybody starts without experience, so no worries ;)

I'll wait for your PR and then give you feedback.

@MrWolfZ
Copy link
Owner

MrWolfZ commented Jan 31, 2018

I have just released version 2.2.0 which fixes this issue.

@MrWolfZ MrWolfZ closed this as completed Jan 31, 2018
@icepeng
Copy link
Contributor Author

icepeng commented Feb 2, 2018

I submitted PR yesterday #40

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants