Checking the alignment of celestial bodies for an array of entities

Seeking to implement validation for a form featuring checkbox selections with corresponding number inputs. When a user selects a profession checkbox, they must enter the number of years of experience they have in the input next to it. The array structure is as follows (default experience set to 1):

const fieldsOfEng = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: 1,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: 1,
  }
]

If verifying user selection against professions array was the sole focus, the schema would resemble:

export const userInfoSchema = z.object({
  professions: z
    .string()
    .array()
    .refine((val) => val.some(profession => 
      fieldsOfEng
        .map((field) => field.name)
        .includes(profession))
})

Handling the input registration through react-hook-form:

{fieldsOfEng.map((field) => {
     return (

     <input
      {...register("professions")}
      value={field.name}                               
      type="checkbox"
     />

   )}

--------------------WHAT I WANT:

Integration of an 'experience' field into the schema for comprehensive validation. A tentative schema structure could be (not accurate yet):

  professions: z
    .array(
      z.object({
        name: z.string(),
        experience: z.number(),
      })
    )
    .refine(({name}) =>
      name.some(({ profession }) =>
        fieldsOfEng.map((field) => field.name).includes(profession)
      )
    )
    .refine(({ experience }) => {
      experience.some((exp) => exp > 1);
    }),

Form layout adjustment considering the schema update:

{fieldsOfEng.map((field) => {
     return (

     <input
      {...register("professions.name")}
      value={field.name}                               
      type="checkbox"
     />

     <input
      {...register("professions.experience")}
      value={field.experience}                               
      type="number"
     />

   )}

Although form tweaking is possible, the primary focus lies on refining the schema.

Answer №1

If you need to verify a list of objects based on this Schema

const engineeringFields = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: 1,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: undefined,
  },
];

This is how I would approach it

const userInformationSchema = z.object({
  id: z.string(),
  name: z.string(),
  experience: z.number().optional()
})

// Insert this object into an array
const usersInformationSchema = z.array(userInformationSchema)

Answer №2

Just giving an update on my progress. I'm getting closer to fixing my schema validation but I'm having trouble with the submission. Trying to make react-hook form's errors display correctly with template literals, but currently it's just showing nothing. I do know there's an error though because I can see the "professions:" string that I added in the p-tag.

Here's the data for the checkboxes I'm validating with zod:

const fieldsOfEng = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: undefined,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: undefined,
  },

Validation schema: Checking if the selected name is in the fieldsOfEng array and ensuring the experience is greater than 1.

const userInfoSchema = object({
professions: z
    .object({
      name: z
        .string()
        .refine((name) =>
          fieldsOfEng.map((field) => field.name).includes(name)
        ),
      experience: z.number().refine((experience) => experience > 1),
    })
    .array(),
});

Using React hook form:

type userInfoType = z.infer<typeof userInfoSchema>;

  const {
    register,
    watch,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<userInfoType>({
    resolver: zodResolver(userInfoSchema),
  });

Form setup: I'm using template literals for registering each input. It was a struggle to figure out, but it's the only way I've found to get the data to display correctly through react-hook-form's 'watch' method.

<fieldset>
      <legend>Practicing fields of engineering</legend>
      {fieldsOfEng.map((field, i) => {
        return (
          <div key={field.id}>
            <div>
              <input
                {...register(`professions.${i}.name`)}     <--REGISTERED HERE
                value={field.name}
                type="checkbox"
              />
              <div>
                <input
                  {...register(`professions.${i}.experience`)}    <--REGISTERED HERE
                  type="number"
                  value={field.experience}
                  placeholder="Yrs Experience"
                />
              </div>
            </div>

            <div>
              {errors.professions && (
                <p>
                  professions:
                  {errors.professions.message}
                </p>
              )}
            </div>
          </div>
        );
      })}
    </fieldset>

Answer №3

In my opinion, Zod will not generate error messages if the array is submitted without default values. To avoid this, make sure to set the default values for professions in the useForm hook:

const form = useForm<z.infer<typeof userInfoSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      professions: [],
    },
    mode: "onChange",
  }); 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Angular material checkbox has a mind of its own, deciding to uncheck

I am having an issue with a list displayed as checkboxes using angular-material (Angular 7). Below, I will provide the code snippets for both the .html and .ts files. Every time I click on a checkbox, it gets checked but then immediately becomes unchecked ...

Benefits of using props destructuring in React - beyond just being a syntactic shortcut

This idea might not be exclusive to React, but I've struggled to discover a compelling reason beyond concise and easier-to-read code. ...

PHP and JavaScript are two powerful programming languages that are

While I understand that PHP and JavaScript operate in different locations, I am curious to know if there is a way to incorporate some PHP code into my JavaScript file. I need to create unique URLs for linking to profiles and news posts, such as /#/news/IDH ...

The Vue instance methods provide a way to access and manipulate formatted properties

I am looking to implement a method that will generate the appropriate email format to be used as the href value in an anchor tag. This method should return the formatted string in the following format: "mailto:[email protected]". var facultyInformat ...

Prevent using href for opening the browser when clicked

In the control, there is an href link that triggers a javascript function and passes a variable to it: <a href="<%#XPath("link").ToString()%>" onclick="return getLink(this)">Link</a> I'm looking for a way to prevent the browser fro ...

Transforming the input button into images

I'm new to JavaScript and I'm looking to change the show button and hide button to images instead. The show button image should be different from the hide button image. Can anyone guide me on how to achieve this? Click here for reference $( ...

Issue between Promise and EventEmitter causing race conditions in ExpressJS

Currently, I am working on a NodeJS/Express web application where users can upload files that are then parsed using the connect-busboy module and saved to a database with Sequelize. Once the data is stored, I aim to redirect the user to a specific page. Ho ...

Unit testing an Angular service using Jasmine with a JSON object schema in Angular 2/4

Looking for assistance with unit testing a service I have. The service includes a current json array object that is functioning properly when the observable is subscribed to. However, I seem to be encountering issues with my unit test setup. Can anyone pr ...

Exploring the nuances of useEffect() functionality and the impact of extra re-renders

I ran some tests using a dummy component and noticed an unusual pattern in the console output: Rendering: 0 Triggered: 0 Rendering: 4 Triggered: 4 Rendering: 4 I'm having trouble figuring out why this is happening. On the first render, the foll ...

A promise is given when a value triggers a function

Having a problem with my code in the second function. When I log inside the function, it works fine. But when I assign a variable and call the function, it returns a pending promise instead of true or false. const mongoose = require('mongoose') c ...

Setting up parameters and arguments in Vuex mutations: A guide

I am currently developing a todo list application using Vue.js, Vuex, and Firebase. The functionality of the app seems to be in working order with the Store file effectively managing the retrieval and display of entered todo items to and from Firestore. Ho ...

What is the best approach to creating customizable modules in Angular2?

I'm exploring the most effective approach to configuring modules in Angular 2. In Angular 1, this was typically achieved through providers. As providers have been altered significantly, what is the preferred method for passing configuration parameters ...

Encountering an issue with ReactJS + Redux where the error message states: "Error in prop type: The Right-hand side of 'instanceof' cannot be called"

Currently working on a web app project in React with Redux for global state management. A puzzling issue has arisen - we're receiving warnings in the browser console. How can we resolve this? It seems related to prop types declaration, but the soluti ...

Create a separate server session specifically for handling an ajax request?

Currently, I am working with a collection of PHP server-side scripts that manage user session state by utilizing PHP sessions extensively for authenticated users. For the client side within a mobile application and using Jquery ajax, I am striving to esta ...

Choosing2 - incorporate a style to a distinct choice

Let's talk about a select element I have: <select id="mySelect"> <option>Volvo</option> <option value="Cat" class="red">Cat</option> <option value="Dog" class="r ...

Making a synchronous call to a web API using JQuery

Understanding JQuery promises and deferred objects has been a bit of a challenge for me, so please bear with me. I should also mention that my application is built using React, Typescript, and ES6. Let's imagine we have an array of objects: [{ Objec ...

Utilize jQuery to extract various input/select box values and compile them into an array for submission using .ajax()

I am currently facing an issue with dynamically generated forms using PHP and updated with jQuery's .appendTo() function as visitors interact with it. My main goal is to collect all input text and select box values from the current form and submit the ...

Modify the values of an object by utilizing the setter function

How can I utilize the setter method to update existing values of an object and perform mathematical operations? var obj = { set model(object) { //method's logic } }; obj = {x:10, y: 20, p: 15}; obj = { x:10, y: 20, p: 15 set mod ...

Trigger a method within a component when there is a change in the Vuex state

I need to trigger a method inside a component whenever the vuex state changes in TypeScript and Vue.js. While I can access the vuex state value using getters in the template, I am unsure how to access the data within the component class. The vuex state is ...

Passing data between Vue.js components effortlessly without relying on events

At the moment, I am utilizing Laravel Nova. It's worth noting that it operates using vue.js. I've created a personalized vue component which requires the ability to modify data inside another component. This specific component is located in the ...