Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/actions/attendee-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,35 @@ export const queryAttendees = _.debounce(async (input, summitId, callback) => {
})
.catch(fetchErrorHandler);
}, DEBOUNCE_WAIT);

export const queryAttendeesWithTickets = _.debounce(
async (input, summitId, callback) => {
const accessToken = await getAccessTokenSafely();

const endpoint = URI(
`${window.API_BASE_URL}/api/v1/summits/${summitId}/attendees`
);

input = escapeFilterValue(input);
endpoint.addQuery("access_token", accessToken);
endpoint.addQuery("order", "first_name,last_name");
endpoint.addQuery("page", 1);
endpoint.addQuery("per_page", DEFAULT_PER_PAGE);

if (input) {
endpoint.addQuery("filter[]", `full_name=@${input},email=@${input}`);
}

endpoint.addQuery("filter[]", "has_tickets==true");
endpoint.addQuery("filter[]", "has_member==true");

fetch(endpoint)
.then(fetchResponseHandler)
.then((json) => {
const options = [...json.data];
callback(options);
})
.catch(fetchErrorHandler);
},
Comment on lines +860 to +867

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Check async autocomplete loading/error contract:"
sed -n '31,45p' src/components/mui/formik-inputs/mui-formik-async-select.js

echo
echo "Check new query function error path:"
sed -n '839,869p' src/actions/attendee-actions.js

Repository: fntechgit/summit-admin

Length of output: 1502


Return the fetch chain and always invoke the callback, even on error.

This function does not return the fetch promise, so await queryFunction(...) in the autocomplete completes before the fetch does. On fetch error, fetchErrorHandler is called but callback is never invoked and no error is rethrown. In src/components/mui/formik-inputs/mui-formik-async-select.js (line 34), the component awaits this function; if the fetch fails and the callback is not called, setLoading(false) never runs and the autocomplete gets stuck in loading state.

Proposed fix
-    fetch(endpoint)
+    return fetch(endpoint)
       .then(fetchResponseHandler)
       .then((json) => {
         const options = [...json.data];
         callback(options);
       })
-      .catch(fetchErrorHandler);
+      .catch((e) => {
+        fetchErrorHandler(e);
+        callback([]);
+        throw e;
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fetch(endpoint)
.then(fetchResponseHandler)
.then((json) => {
const options = [...json.data];
callback(options);
})
.catch(fetchErrorHandler);
},
return fetch(endpoint)
.then(fetchResponseHandler)
.then((json) => {
const options = [...json.data];
callback(options);
})
.catch((e) => {
fetchErrorHandler(e);
callback([]);
throw e;
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/actions/attendee-actions.js` around lines 860 - 867, Return the fetch
promise and ensure the callback is always invoked on error: change the snippet
to return the fetch(...) chain, and in the .catch handler call
fetchErrorHandler(err), invoke callback with an empty array (e.g., callback([]))
so the consumer’s loading state can clear, then rethrow the error to preserve
error propagation; reference fetchResponseHandler, fetchErrorHandler, callback
and endpoint to locate the code to update.

DEBOUNCE_WAIT
);
4 changes: 2 additions & 2 deletions src/components/mui/mui-qr-badge-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import MuiFormikTextField from "./formik-inputs/mui-formik-textfield";
import QrReader from "../qr-reader";
import { getTypeValue, toSlug } from "../../utils/extra-questions";
import MuiFormikAsyncAutocomplete from "./formik-inputs/mui-formik-async-select";
import { queryAttendees } from "../../actions/attendee-actions";
import { queryAttendeesWithTickets } from "../../actions/attendee-actions";

const buildInitialValues = (extraQuestions) => {
const values = { notes: "", attendee_email: "" };
Expand Down Expand Up @@ -189,7 +189,7 @@ const MuiQrBadgePopup = ({
placeholder={T.translate(
"sponsor_badge_scans.scan_popup.attendee_placeholder"
)}
queryFunction={queryAttendees}
queryFunction={queryAttendeesWithTickets}
queryParams={[summitId]}
formatOption={(attendee) => ({
value: attendee.email.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const SponsorBadgeScans = ({
setShowManualBadgeScanPopup(true);
};

const handleManualScanSubmit = (entity) => {
const handleManualScanSubmit = (entity) =>
addBadgeScan(entity).then(() => {
setShowManualBadgeScanPopup(false);
return getBadgeScans(
Expand All @@ -121,7 +121,6 @@ const SponsorBadgeScans = ({
orderDir
);
});
};

const handleExportBadgeScans = () => {
exportBadgeScans(sponsor);
Expand Down
Loading