ngrx-forms icon indicating copy to clipboard operation
ngrx-forms copied to clipboard

Validating a nested object depending on another data member 🤔

Open anirudhr95 opened this issue 3 years ago • 2 comments

Hello, I have an object - which looks like this 👇

export const user = {
  id: undefined,
  name: undefined,
  createdOn: undefined,
  contact: {
    title: '',
    honorific: '',
    lastName: '',
    firstName: '',
    email: '',
    countryCode: '',
    phone: '',
  } as Contact,
  organizationType: undefined,
  advertiserBrands: box([{
    name: '',
    category: '',
    prohibitions: [],
  }]),
};

I know how to validate objects conditionally i.e, Validate name, only if ID is present like so

const formValidation = updateGroup<CreateOrganizationForm>({
  name: (name, formState) => {
    return (formState.values.id !=== undefined) ? validate(name, required) : validate(name, () => ({}));
   },
  }),
}

However, when I try to do this for a nested object, the scope of FormState is the nested object itself and not the entire object.

What I want to do is - check for Advertiser.Name, Advertiser.category and Advertiser.Prohibitions only if organizationType is not undefined. If I try to do this - the auto-completion in my IDE only shows this :( Screenshot 2021-12-17 at 9 09 14 AM

How do I do this correctly 🤔

  advertiserBrands: updateGroup<AdvertiserBrand>({
    name: (name, formState) => {
      return formState.organizationType === OrganizationType.ADVERTISER ? validate(name, required) : validate(name, () => ({}));
    }
  })

(What I have currently ☝️)

anirudhr95 avatar Dec 17 '21 03:12 anirudhr95

Note: I also tried formState.values and formState.controls, I get the same thing Screenshot 2021-12-17 at 9 12 27 AM

anirudhr95 avatar Dec 17 '21 03:12 anirudhr95

sorry, this might be flakey/not precise with no stackblitz or anything, but essentially you just need to scope your updates to the context of the entire form, so you can query outside the intended updateGroup

const formValidation = updateGroup<CreateOrganizationForm>({
	// @ab:  shorthand for `advertiserBrands`, gets passed explicitly to child `updateGroup`
	// @form:  the parent `FormGroupState`
	advertiserBrands: (ab, form) => updateGroup<AdvertiserBrands>(ab, {
		// @c:  shorthand for `FormControlState`
		name: c => form.value.organizationType === OrganizationType.ADVERTISER ? validate(c, required) : c
	})
})

mminor-dev avatar Mar 18 '22 14:03 mminor-dev