( edition: EditionObject, question: Question, value_: string, questionLabel: string )
| 169 | |
| 170 | */ |
| 171 | const getOptionValues = ( |
| 172 | edition: EditionObject, |
| 173 | question: Question, |
| 174 | value_: string, |
| 175 | questionLabel: string, |
| 176 | ) => { |
| 177 | const { editionId, outline } = edition; |
| 178 | let optionsValues: (string | number)[] = [], |
| 179 | otherValue: string | undefined; |
| 180 | |
| 181 | // if this is a number question that has options defined, take the provided number |
| 182 | // and replace it with the closest available option |
| 183 | const value = |
| 184 | question.template === "number" |
| 185 | ? String( |
| 186 | findClosestValue( |
| 187 | question.options?.map((o) => o.id), |
| 188 | Number(value_), |
| 189 | ), |
| 190 | ) |
| 191 | : value_; |
| 192 | |
| 193 | // CSV fields that hold multiple values are separated with semi-columns |
| 194 | const values = value.split(";"); |
| 195 | for (const value of values) { |
| 196 | // check if a predefined matching option exists based on the option label |
| 197 | // or the option id, for question whose options are generated from a template |
| 198 | const matchingOption = question.options?.find( |
| 199 | (o) => |
| 200 | String(o.label) === String(value) || String(o.id) === String(value), |
| 201 | ); |
| 202 | if (matchingOption) { |
| 203 | optionsValues.push(matchingOption.id); |
| 204 | } else { |
| 205 | if (question.allowOther) { |
| 206 | // handle this value as an "other" answer |
| 207 | otherValue = value; |
| 208 | } else { |
| 209 | console.log(question); |
| 210 | throw new Error( |
| 211 | `🔴 Could not find value "${value}" within options for ${editionId}/${question.id} ("${questionLabel})"`, |
| 212 | ); |
| 213 | } |
| 214 | } |
| 215 | } |
| 216 | return { optionsValues, otherValue }; |
| 217 | }; |
| 218 | |
| 219 | export const loadTokyoDevCSV = async () => { |
no test coverage detected