Summary
On initial page load a gadget-map request fires before a reduction is chosen, sending an empty reduction query param, which the backend correctly rejects with 400.
Observed error
POST https://redux.isu.edu/api/redux/ProblemProvider/gadgets?reduction= → 400
Response body from production:
{
"title": "One or more validation errors occurred.",
"status": 400,
"errors": { "reduction": ["The reduction field is required."] }
}
(With a valid reduction and instance the same endpoint returns 200, so this is purely the empty-param case.)
Root cause
In components/widgets/VisualizationLogic.js, the effect that builds the gadget map is guarded only by problemInstance && problemData — not by chosenReductionType:
useEffect(() => {
if (problemInstance && problemData) { // <-- missing chosenReductionType
setLoadingMap(true);
processReductions(url, chosenReductionType, problemInstance)
.then(/* ... */)
.finally(() => setLoadingMap(false));
}
}, [problemData, url, chosenReductionType, problemInstance]);
On boot, problemData / problemInstance populate before chosenReductionType, so processReductions(url, "", ...) runs and calls requestGadgetMap(url, "", ...) → gadgets?reduction=.
Proposed fix
Add chosenReductionType to the guard so the request only fires once a reduction is selected:
if (chosenReductionType && problemInstance && problemData) {
The parallel effect a few lines down (the visualizationState.reductionOn block, also calling processReductions) has the same gap and should get the same guard.
Environment
Frontend (this repo) proxied to the production backend at https://redux.isu.edu.
Summary
On initial page load a gadget-map request fires before a reduction is chosen, sending an empty
reductionquery param, which the backend correctly rejects with400.Observed error
Response body from production:
{ "title": "One or more validation errors occurred.", "status": 400, "errors": { "reduction": ["The reduction field is required."] } }(With a valid
reductionand instance the same endpoint returns200, so this is purely the empty-param case.)Root cause
In
components/widgets/VisualizationLogic.js, the effect that builds the gadget map is guarded only byproblemInstance && problemData— not bychosenReductionType:On boot,
problemData/problemInstancepopulate beforechosenReductionType, soprocessReductions(url, "", ...)runs and callsrequestGadgetMap(url, "", ...)→gadgets?reduction=.Proposed fix
Add
chosenReductionTypeto the guard so the request only fires once a reduction is selected:The parallel effect a few lines down (the
visualizationState.reductionOnblock, also callingprocessReductions) has the same gap and should get the same guard.Environment
Frontend (this repo) proxied to the production backend at
https://redux.isu.edu.