S
SolidJS3mo ago
jack

useSubmission pending state resolves on url change?

i have some optimistic ui, with roughly the following structure:
view = "edit" | "read", based on searchParams
data = fetch data from server
editable = copy of data we can write to (what we render)

when the user clicks save =>
invoke save fn() (which is an action())
**set view -> "read" (rest of ui is already optimistically set)

if no error thrown (via try)
await revalidate() // wan't to make sure we have server state befoe confirming success
toast("good")
if error thrown (via catch)
await revalidate() // reset to good state
toast("bad")

view = "edit" | "read", based on searchParams
data = fetch data from server
editable = copy of data we can write to (what we render)

when the user clicks save =>
invoke save fn() (which is an action())
**set view -> "read" (rest of ui is already optimistically set)

if no error thrown (via try)
await revalidate() // wan't to make sure we have server state befoe confirming success
toast("good")
if error thrown (via catch)
await revalidate() // reset to good state
toast("bad")

then somewhere else i use useSubmission(save) and disable buttons based on pending state as i don't want user's editing lists that aren't accurate to server state. the weird thing is, when i include the logic above with the **, the useSubmission state basically dies. it returns to undefined, and my buttons are don't disabled if instead i wait to set view -> "read" until after i've checked the result of the server call, then the pending state works perfectly (which i can't really do, otherwise the illusion of the optimistic ui is gone) wondering if this is expected, or perhaps i'm doing something wrong? I can post code tomorrow if this doesn't make sense, thanks!
2 Replies
Madaxen86
Madaxen863mo ago
without code, this is difficult. Actions do revalidate all cached functions, unless you tell it not to. Maybe you can provide a stack blitz with minimal reproduction.
jack
jackOP3mo ago
It’s not really the revalidation that’s my issue but yes I can show some code later important point: args.setView() updates searchParams. i think this is messing up action state for some reason
save: action(async () => {
// ... grab the data to send to server
toasts.submitting();

try {
// when i call this, the issues happen
args.setView("read");

// this is rpc via "use server"
await api.updateUserSelectionsByOrderDiff({
source: sourceTuples,
edited: editedTuples,
userId: args.userId(),
});

// await so i don't fire my toast until the ui has the revalidated data
await revalidate(getSelections.keyFor(args.userId()));

toasts.succeed();
} catch (error) {
// fallback to old state if error
if (error instanceof Error) {
await revalidate(getSelections.keyFor(args.userId()));

toasts.error(`An error occurred, please try again.`);
}
}
}),
save: action(async () => {
// ... grab the data to send to server
toasts.submitting();

try {
// when i call this, the issues happen
args.setView("read");

// this is rpc via "use server"
await api.updateUserSelectionsByOrderDiff({
source: sourceTuples,
edited: editedTuples,
userId: args.userId(),
});

// await so i don't fire my toast until the ui has the revalidated data
await revalidate(getSelections.keyFor(args.userId()));

toasts.succeed();
} catch (error) {
// fallback to old state if error
if (error instanceof Error) {
await revalidate(getSelections.keyFor(args.userId()));

toasts.error(`An error occurred, please try again.`);
}
}
}),
and this is the code i pass down to my buttons via props to use for disabled attr
const disableActionButtons = createMemo(() => {
return useSubmission(buttonActions.save).pending;
});
const disableActionButtons = createMemo(() => {
return useSubmission(buttonActions.save).pending;
});
Update: Almost positive it's a result of the url change; when i remove the url from the picture and just have it be a signal toggle, the pending state works properly
Want results from more Discord servers?
Add your server