4
\$\begingroup\$

I have a array-object which should look something like this and is used to create a form

const questions = [
 {
 condition_action: "selected",
 label: "What is your name?",
 question_type: "free_text",
 required: true,
 },
 {
 condition_action: "selected",
 label: "Where do you live?",
 question_options: [
 {
 label: "India",
 },
 {
 label: "china",
 },
 {
 label: "japan",
 },
 ],
 question_type: "single_answer",
 required: false,
 },
];

Now, When user is done creating the form, I have to validate the data and add a key name order in the above snippet (more below) to array-object (main array and question_options)

For validation, There are two conditions

  1. Main array-object should have a label (if not throw error).
  2. Question option should have at-least 1 item and the label inside it can't be empty

Basically, question_options is for multiple-select and single select drop down. So question_option should only contain value if question_type key in the above snippet is single_answer or multiple_answer

The backend api also require attribute order on the main question array and question_options array (yeah even though it's an array we could determine the order through index)

So this is the code I wrote

 const validateAndFormatdata = (questions) => {
 // we will change this to true if error exist and send it at return of this function
 let errorsExsist = false
 // we are formating data here, if error exist while validation, we change flag
 const formatedData = (questions || []).map((question, index) => {
 // delete all previous errors since we are iterating and we don't care about our previous errors
 if (Object.prototype.hasOwnProperty.call(question, "errors")) {
 delete question.errors
 }
 // There can be more than one thing wrong, hence using an array
 const newErrors = []
 // if label does not have value, add it it in errors array
 if (question.label === "") {
 newErrors.push(errorReasons.missingLabel)
 }
 if (
 question.question_type === "multiple_answer" ||
 question.question_type === "single_answer"
 ) {
 const questionOptions = _.filter(question.question_options, "label").map(
 (option, position) => {
 return {
 ...option,
 order: position
 }
 }
 )
 // if question optiond does not have single item, add it it in errors array
 if (questionOptions.length < 1) {
 newErrors.push(errorReasons.noOption)
 } else {
 question.question_options = [...questionOptions]
 }
 } else if (Object.prototype.hasOwnProperty.call(question, "question_options")) {
 // remove question otpions of question type isn't single or mult-text
 delete question.question_options
 }
 if (newErrors.length > 0) {
 errorsExsist = true
 question.errors = newErrors
 }
 return { ...question, order: index }
 })
 return {
 errorsExsist,
 data: formatedData
 }
 }

Question: I was wondering if someone can share review, optimisation and suggestions (including naming)?

asked Jul 25, 2020 at 23:51
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I have made some changes and added comments for each change.

// add the default array here ------------↓ 
const validateAndFormatdata = (questions = []) => {
 let errorsExist = false, // <- typo in exist
 // in case you want to add new types
 optionTypes = new Set(["multiple_answer", "single_answer"]);
 
 // no need to check for || [] because default is added
 // remove the errors property here itself by using destructuring
 const formattedData = questions.map(({ errors, question_options, ...question }, index) => {
 // because of the destructuring, question is a new object.
 // So, will not mutate the original object
 question.order = index;
 const newErrors = []
 
 // checks if label exists and if it is an empty string
 if (!question.label) {
 newErrors.push(errorReasons.missingLabel)
 }
 
 if (optionTypes.has(question.question_type)) {
 const questionOptions = question_options
 .filter(q => q.label)
 .map((option, order) => ({ ...option, order }));
 
 // === 0 is much more clearer to read
 if (questionOptions.length === 0) {
 newErrors.push(errorReasons.noOption)
 } else {
 // no need for [...]. It's a new array
 question.question_options = questionOptions
 }
 }
 // no need for delete question.question_options because it is destructured
 if (newErrors.length > 0) {
 errorsExist = true
 question.errors = newErrors
 }
 return question;
 })
 
 return {
 errorsExist,
 data: formattedData
 }
}
answered Jul 26, 2020 at 13:27
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.