Closed malibeg closed 7 months ago
You can use lazy
to return different schema depending on the value type
Thanks this works:
import React from "react";
import * as yup from "yup";
import "./styles.css";
model = {
questionnaire: {
name: "set name",
description: "description",
questions: [
{
id: "TextQuestion1",
text: "First Name",
type: "text",
answer: "bla",
},
{
id: "MultilineQuestion1",
text: "Last Name",
type: "multiline",
answer: "bla",
},
{
id: "NumericQuestion3",
type: "number",
text: "your Age",
NumValue: 5,
},
{
id: "ChoiceQuestion4",
type: "choice",
availableColours: ["red", "green", "blue"],
favColours: "green",
},
],
},
};
import * as Yup from "yup";
const schema = Yup.object().shape({
questionnaire: Yup.object().shape({
name: Yup.string().required("Name is required"),
description: Yup.string().required("Description is required"),
questions: Yup.array()
.of(
Yup.lazy((item) => {
switch (item.type) {
case "text":
return Yup.object().shape({
id: Yup.string().required("ID is required"),
text: Yup.string().required("Text is required"),
type: Yup.string().required("Type is required"),
answer: Yup.string().required("Answer is required"),
});
case "multiline":
return Yup.object().shape({
id: Yup.string().required("ID is required"),
text: Yup.string().required("Text is required"),
type: Yup.string().required("Type is required"),
answer: Yup.string().required("Answer is required"),
});
case "number":
return Yup.object().shape({
id: Yup.string().required("ID is required"),
text: Yup.string().required("Text is required"),
type: Yup.string().required("Type is required"),
NumValue: Yup.number().required("NumValue is required"),
});
case "choice":
return Yup.object().shape({
id: Yup.string().required("ID is required"),
type: Yup.string().required("Type is required"),
availableColours: Yup.array()
.of(Yup.string().required())
.required("Available colours are required"),
favColours: Yup.string().required(
"Favourite colour is required"
),
});
default:
return Yup.object();
}
})
)
.required("Questions are required"),
}),
});
export default function App() {
return (
<div className="App">
<p>{JSON.stringify(schema.validateSync(model, { returnError: true }))}</p>
{/* <p>{JSON.stringify(workflow)}</p> */}
{/* <p>{schema.isValidSync(workflow) ? "Valid" : "Invalid"}</p> */}
</div>
);
}
How to create yup schema for array of objects of different type.
E.g. if I receive from backend questionnaire json where questions can be text input, choice, or numeric input. Every question object has unique id and type: