Practical web UI/UX / personal lessonsLesson 9 of 15
Practical web UI/UX · Lesson 9

Represent waiting, failure, and success honestly

A click starts a request; it does not prove the request succeeded. Interface state should follow what the system knows.

By the end: distinguish draft, pending request, accepted value, failure, and stale response.

Separate local intention from accepted state

The draft is what the person is editing. The accepted value is what the simulated service has acknowledged. During a pending request, those can differ. A premature "Saved" message collapses that distinction and can cause someone to leave before their work is accepted.

The reference clears the draft and claims success on submission. The revised editor keeps the draft and reports waiting. Response controls let you hold a request indefinitely, fail it, or acknowledge it. They are explicit simulation controls, not real network requests or measured latency.

Read the evidence behind a save message

Imagine changing a workshop title before sending its details to a colleague. You type Clay basics plus, press Save title, and see Saved! You would reasonably expect the next person to see the new title. Yet the reference editor still shows Clay basics as its accepted value while a request is pending. Those two statements conflict. The problem is not an unattractive message. The message licenses a decision, such as leaving the editor, before the available evidence supports that decision.

Four separate pieces of information explain this conflict. The draft is the text currently in the field. The request snapshot is the text captured when Save title is activated. The accepted value is the last title acknowledged by the simulated service. The request identifier distinguishes one attempt from another. Before submission there is no pending snapshot or identifier, even though the draft already differs from the accepted title. Editing alone changes an intention, not the acknowledged record shown below the field.

One title edit, four separate facts

Static example: before submission
Visible draft
Clay basics plus
Accepted demo value
Clay basics
Current request
none
No request snapshot exists yet.
Static example: revised editor after Save title
Visible draft
Clay basics plus
Pending snapshot
Clay basics plus
Accepted demo value
Clay basics
Current request
#1
Submission captures a proposed value without changing the accepted value. The matching words in the draft and snapshot do not make them the same piece of state.

On submission, the model trims spaces from the beginning and end of the draft to make its snapshot. In the retained-draft editor, the visible draft itself stays unchanged. A draft containing spaces around Clay basics plus can therefore produce an accepted value without those outer spaces after success. This is a small but useful distinction between what the person typed and what the operation proposes to accept. Internal spaces remain. A draft consisting entirely of spaces cannot start a request.

Waiting is a state with restricted actions, not an estimate of completion. While a request is pending, the field and Save title button are disabled. The accepted value remains available to read. This combination tells someone both why they cannot continue editing and which title is still acknowledged. The simulation has no clock that eventually resolves the operation. A request can remain pending indefinitely until you use a response control or stop the local wait. Neither elapsed time nor a spinning shape would supply acknowledgment.

Read the static examples below as two interpretations of the same intermediate state. Both concern the same proposed title and unchanged accepted title. One says Saved! while the other describes waiting. This holds the underlying facts constant so the wording mismatch is visible. Do not infer that a different background color repairs the reference. If it still reports completion early, its central promise remains wrong. Text, available actions, and displayed values must describe compatible states for someone to make an informed next move.

The same pending operation described two ways

Static reference state
Workshop title
Empty field; editing unavailable
Saved!
Accepted demo value
Clay basics
Current request
#1, snapshot Clay basics plus
Static retained-draft state
Workshop title
Clay basics plus; editing unavailable
Waiting for acknowledgment. Draft retained.
Accepted demo value
Clay basics
Current request
#1, snapshot Clay basics plus
Both panels still await the same kind of evidence. Saved! misdescribes that state. Retention also differs, so this is not an isolated test of wording alone. These are text specimens, not operating editors.

Before running the lab, predict what Deliver failure should do to the accepted title. It should leave Clay basics unchanged, because no successful acknowledgment has arrived. Now predict what information would be needed to try again. The intended title must still be available somewhere, ideally in the editor. These predictions separate two failures that often appear together. Premature success misstates evidence, while clearing the draft removes recoverable work. Either defect can exist without the other, so both deserve inspection during a repair.

Try the interface

Your task: Save in both editors, then deliver failure. Retry the revised draft. Also abandon a pending wait, start another request, and deliver the old reply.

Hold, fail, or acknowledge a save

Studio Desk demonstration. Actions affect this page only, not a real booking, account, or payment.

Premature-success reference

No current request.

Accepted demo value: Clay basics

Current request: none

Drive the simulated response

Retained-draft editor

No current request.

Accepted demo value: Clay basics

Current request: none

Drive the simulated response

StateDraftAccepted value
IdleEditableLast acknowledged value
Pending, revisedRetained, temporarily lockedUnchanged
Failure, revisedRetained and editableUnchanged
SuccessRetained in revised editorUpdated from request snapshot
Stale replyUnchangedUnchanged
The reference deliberately clears its draft and reports Saved before acknowledgement. The table describes the guarded state model.

These controls drive deterministic local transitions. There is no timer, backend, network request, or claimed latency. Each editor is independent. Requests remain pending until you respond or stop waiting. Reset editors discards both drafts, accepted values, and request histories.

Follow a failed attempt through recovery

Use Reset editors so both comparisons begin with Clay basics plus in the field and Clay basics below it. Activate Save title in both panels, but do not deliver a response yet. Compare the field contents, the feedback, and the current request number. The reference has removed its draft and says Saved! The retained-draft editor keeps its text and reports waiting. Both still have a pending request. The reference message contradicts the pending operation.

While both requests are pending, try to edit their fields and activate Save title again. Those actions are blocked in both panels. This matters because the poor reference is not simply an example with every safeguard removed. It shares the duplicate-submission block with the revised editor. If you credit the revised message with preventing every duplicate action, the comparison would not support that conclusion. Identify which behavior actually differs before explaining why one panel better supports the task of retaining and saving the intended title.

Deliver failure in each panel. Both pending identifiers disappear, and both accepted titles remain Clay basics. Now the retained-draft editor has the intended title ready for another attempt, whereas the reference has an empty field. The error in the revised panel names the failed operation and says the draft is retained. The reference offers only a general failure message. Count neither message as a successful save. A usable recovery path should preserve the value someone needs to repair or repeat the action, not merely announce trouble.

A failed save does not erase the accepted title

Revised-editor eventVisible draftAccepted valuePending request
ResetClay basics plusClay basicsnone
Save titleClay basics plus, lockedClay basics#1: Clay basics plus
Deliver failureClay basics plus, editableClay basicsnone
Save title againClay basics plus, lockedClay basics#2: Clay basics plus
Deliver successClay basics plus, editableClay basics plusnone
Read down the accepted-value column. Failure ends an attempt but leaves the old title intact. The retry can reuse the draft while receiving a new identity.

Retry by activating Save title in the retained-draft editor. Its next request has a larger number, even though its proposed title can be identical to the failed attempt. Deliver success and compare the accepted title with the captured snapshot. The model updates the accepted value only now. The field remains populated, and the message becomes Save acknowledged. In the reference, you would first have to re-enter a title. Do not use real workshop or contact data to test this difference; the supplied fictional title already exposes it.

Next edit the revised title after success without saving it. The feedback returns to No current request, but the accepted title remains the previously acknowledged one. This state is legitimate. It means the current edit has not started another operation. Notice that the message does not explicitly say that the draft is unsaved. A production editor might need that additional distinction, especially before navigation. The visible draft and accepted value let you inspect it here, but they do not constitute a complete leave-with-unsaved-changes policy.

Use the failure trace below to explain recovery without relying on your memory of button presses. Its important intermediate point is a retained draft beside an unchanged accepted value after failure. That combination permits another attempt without pretending that failure erased the old record. A real service could reject a title for permissions or a naming rule instead of temporary unavailability. In that case, retrying the same text may never help. Useful feedback must distinguish a repairable value problem from a reason to wait or seek authorization.

Recovery needs the intended value as well as a message

Static reference after failure
Workshop title
Empty field
Something went wrong. The cleared draft is not restored.
Accepted demo value
Clay basics
Before retrying, re-enter the intended title.
Static revised editor after failure
Workshop title
Clay basics plus
Save failed. Your draft is retained; retry when ready.
Accepted demo value
Clay basics
The intended title is already available for another attempt.
The retained draft reduces reconstruction after a known failure. It does not establish that repeating the same request will fix a permission problem or a rejected naming rule.

Make failure recoverable

A spinner without an explanation can leave users unsure whether to wait, retry, or leave. State what is pending, retain recoverable work, and provide a policy for errors or long waits. Do not invent an exact progress percentage if the operation provides no meaningful progress measure.

This model blocks duplicate submissions while pending. That protects one interface instance, not the entire system against duplicate requests. Production operations may still need server-side idempotency or deduplication. Retry preserves the revised draft; the reference requires re-entry after it has cleared its fields.

Make the waiting state understandable

A pending state should answer a practical question about the current task. For a title edit, someone needs to know that saving has started and that acknowledgment has not arrived. A percentage implies measurable partial completion, but this model only knows whether a request is outstanding. A changing decoration could communicate activity, yet would still need readable text and a policy for a long wait. The lab instead leaves the state stable until you explicitly deliver an outcome.

Compare the phrase Save failed with a hypothetical message saying Your title was deleted. The first describes this model's failed attempt to replace an accepted title. The second falsely suggests that the previous value disappeared. A failure message needs an object and an outcome precise enough to guide the next action. It should also state which work survived when that is relevant. Here the unchanged accepted title and retained draft are different kinds of surviving information. Showing both avoids forcing someone to reconstruct the situation from a vague warning.

What the pending screen can actually claim

Static specimen of the revised pending state
Workshop title
Clay basics plus
Editing and Save title are unavailable during this request.
Waiting for acknowledgment. Draft retained.
Accepted demo value
Clay basics
Current request
#1
Simulation actions available in the working lab: Deliver success, Deliver failure, Stop local wait.
The pending identifier and unchanged accepted value support a waiting message, not a completion percentage. The response actions belong to the teaching simulation, not to an ordinary customer save form.

The feedback paragraphs use status semantics so their changes can be exposed to assistive technology without automatically moving keyboard focus to them. Focus is the current keyboard interaction position; an announcement is information about a change. Those are different mechanisms. Pressing a save button does not require replacing the entire task with a modal acknowledgment. Exact spoken behavior still depends on the browser and assistive technology. A status role does not prove that announcements have been tested or understood.

Inspect the save form with the keyboard and notice what becomes unavailable during a pending request. Do not assume a disabled control will retain focus in the same way in every environment. Check that a useful next control can be reached and that the waiting explanation remains readable. After a delivered failure, the field becomes editable again. This lab does not implement a special focus-return routine for the save editor. That limitation should prompt a focused interaction check, not an invented description of behavior that the example lacks.

Blocking editing is one policy for keeping the visible draft aligned with the pending operation. Another application might allow further edits while saving an earlier snapshot. Suppose it sends Clay basics plus, then lets you type Clay basics evening before the reply arrives. A successful reply would acknowledge plus, not evening. The interface would need to show that the latest draft still needs saving. This is a paper counterexample, not an extra mode in the lab. It explains why a snapshot remains conceptually separate even when this editor temporarily locks typing.

Why an editable draft would still need a snapshot

Actual lab policy while request #1 is pending
Visible draft, locked
Clay basics plus
Request #1 snapshot
Clay basics plus
Accepted before reply
Clay basics
Paper counterexample, not a lab mode
Visible draft, edited further
Clay basics evening
Request #1 snapshot
Clay basics plus
Accepted after success for #1
Clay basics plus
The latest draft would still need saving.
Allowing edits during a request would create a new unsaved draft, not change the already captured request. This hypothetical policy requires feedback that distinguishes the two titles.

After Reset editors, test a draft with only spaces in the retained-draft editor. Save title should remain unavailable. Replace it with a short fictional title surrounded by spaces, submit it, and deliver success. Compare the visible draft with the accepted value, which uses the trimmed snapshot. This tests the boundary between an editable value and a request, not visual preference. Reset again when finished; reset discards both editors' drafts, accepted values, and request histories, so it is not a production recovery mechanism.

Reject stale replies without inventing cancellation

Responses can arrive after a screen or draft has changed. Associate a response with the request it belongs to. The demo gives each request an increasing identifier and ignores replies that do not match the current pending request. A late reply must not overwrite a newer accepted state.

Stopping a local wait does not prove a real server cancelled its work. In this bounded model, abandoning a wait only removes the request from the local pending state. A production service may need to reconcile an uncertain outcome before allowing a risky retry. No timer or animation clock is used to infer success.

Keep late responses attached to their attempts

A late response is easiest to understand by writing down two intended titles. Reset editors and use the retained-draft panel. Save Clay basics plus as request 1, then activate Stop local wait. The pending request disappears locally, and the observation explains that this does not prove server cancellation. Change the field to Clay evening and save again. Request 2 now represents a different snapshot. You have two historical attempts to reason about, even though only the second is currently pending in the editor.

Before delivering the old success, predict the accepted value and current request afterward. The old reply belongs to request 1, so the guard rejects it while request 2 is pending. Clay basics remains accepted, Clay evening remains the visible draft, and request 2 continues waiting. Now deliver the current success. The accepted title becomes Clay evening. Deliver the old success once more. With no matching pending request, it still cannot replace the acknowledged value. The identifiers prevent a visible regression to the earlier intended title.

An old success cannot complete the new request

Event in revised editorCurrent pending snapshotAccepted title
Reset, then Save title#1: Clay basics plusClay basics
Stop local waitnoneClay basics
Edit to Clay evening; Save title#2: Clay eveningClay basics
Deliver old success for #1#2: Clay eveningClay basics
Deliver current success for #2noneClay evening
Deliver old success for #1 againnoneClay evening
The old reply matches neither request #2 nor an empty pending slot. The guard protects this editor from stale display updates; it makes no claim about server effects of the abandoned attempt.

The guard works by comparing identities, not by deciding which title looks newer. Two different attempts may contain the same text, so comparing strings cannot replace request identity. Conversely, different texts do not prove that a reply is irrelevant to the operation that produced it. The identifier associates replies within each editor. Reset clears that editor's history. Nothing here establishes globally unique request numbers across browsers, persistence after reload, or coordination between separate people editing a real workshop.

Stopping the local wait only changes what this interface is waiting for. In a real service, the abandoned operation might still succeed. Ignoring its late reply protects the local display from an outdated update, but does not reverse any server effect. If the operation charged money or consumed scarce places, a retry could create another effect unless the service supplied stronger rules. A request identity used for display filtering is therefore different from a server-supported mechanism that recognizes repeated operations and prevents duplicate business effects.

Read the alternative production copy below as proposed wording for an uncertain outcome, not a claim that this lab checks a server. A title edit may tolerate another replacement, while a payment may require checking the original operation first. The interface needs enough information to choose an honest recovery action. Calling an abandoned request Cancelled would hide that uncertainty. Likewise, showing Failed solely because a timer expired would confuse a missing response with proof of rejection. This example deliberately uses explicit replies instead of making that inference.

Stopped waiting is different from cancelled work

Actual local observation after Stop local wait
Local wait stopped. This does not prove server cancellation.
Current request
none
Only the local pending state has been removed.
Proposed production wording, not implemented here
We have not confirmed the outcome of the previous request. Check its status before sending another payment.
This wording would require a real status-check or safe-retry contract. The title lab provides neither.
A missing acknowledgment leaves an uncertain business outcome in a real service. Honest wording cannot replace the backend mechanism needed to determine that outcome.

Finish by explaining the observed result in terms of the task. The revised editor preserves the proposed title through a known failure, waits for evidence before reporting success, and prevents an old reply from replacing the current accepted value. It does not prove safe retries for arbitrary operations. The lab also changes retention and wording together, so completing the comparison cannot isolate their separate effects on user performance. To investigate either cause, hold the other behavior constant and observe whether people save the intended title and recognize its outcome.

Exercises

Explain an uncertain outcome

A payment request times out, but the server may have charged the account. Is a plain "Try again" button sufficient?

Hint

A missing response is not proof of no effect.

Worked answer
ObservedNot established
No response receivedNo charge occurred
Button disabledNo other request exists
Retry clickedSafe duplicate handling
Transport evidence and business outcome differ.

No. First determine whether the original operation succeeded through a suitable status check or idempotent retry protocol. Explain the uncertainty without falsely claiming a failure or success. The UI needs a backend contract; a disabled button alone does not prevent duplicate effects.

Handle an old response

Request 1 is no longer current. Request 2 is pending. A success reply for request 1 arrives. What should this demo do?

Hint

Compare the reply identity with the current pending identity.

Worked answer
EventLocal result
Reply id 1Does not match pending id 2
Accepted valueUnchanged
Request 2Still pending
The guard protects the local state, not a distributed transaction.

Ignore the stale reply for the current editor state. Keep request 2 pending and leave the accepted value unchanged. A real service may still need reconciliation of the old operation; ignoring a UI update does not erase server-side effects.

Sources and further reading

Selected guidance and technical definitions were reviewed, not a complete usability literature or accessibility audit. The interfaces are original teaching examples. They do not establish measured improvements in task performance. These optional links are not runtime dependencies.