← All articles

Clearing stale child selections

Replacing child options does not clear an already selected child value. Clear both so an invisible stale identifier cannot be submitted.

t.Turgay
Clearing stale child selections

A user changes the parent selection, the child list reloads, but the old child ID remains in the model. The control may even look empty while that stale value is still submitted. Dependent selections need a validity transition as soon as the parent changes, not just another options request.

Invalidate the old relationship deliberately

This independent .NET 10 console example reduces the form to a dictionary. Parent one permits children ten and eleven; parent two permits twenty. Starting with one/ten and changing to two clears the selected child.

var options=new Dictionary<int,int[]> { [1]=[10,11],[2]=[20] };
int parentId=1; int? childId=10;
void ChangeParent(int next)
{
    if(!options.ContainsKey(next))throw new ArgumentException("Unknown parent");
    parentId=next;
    childId=null;
}
ChangeParent(2);
Console.WriteLine($"parent={parentId};selected={childId?.ToString()??"none"};options={string.Join(",",options[parentId])}");

The output is parent=2;selected=none;options=20. The ordering matters: validate the proposed parent first, then update it and clear the child. An unknown parent should not destroy an otherwise valid selection. Null also communicates absence more clearly than a magic zero that could be mistaken for an actual identifier.

The child control has its own states

A real control can be waiting for a parent, loading, populated, legitimately empty or failed. An empty result is not the same as a failed API call. Provide a retry path for failure, and do not leave options belonging to the previous parent selectable under the new one.

Clear the child identity immediately when the parent changes. Disabling the dependent field while loading can prevent an accidental selection, but its reason should remain understandable. A grey control alone does not explain what the user should do next.

Responses can arrive out of order

If A is selected and then B, B's request may finish first. Applying A's late response would display A's children while the model still contains B. Use cancellation or a monotonically increasing request identity and accept only the latest result. Awaiting each callback does not serialize independent user events automatically.

Cancelling a request does not necessarily undo remote work, so stale-result protection still matters. Keeping the requested parent ID alongside its options provides another useful consistency check when applying the response.

Opening an existing record is not a user change

An edit screen initially receives both selected IDs. Running the ordinary “parent changed” handler during hydration can erase the stored child before the user edits anything. Load the parent and appropriate options, then verify that the existing child remains valid. Keep that initialization flow distinct from a later user action.

If the existing child has become inactive, do not silently substitute another option. Explain why the relationship needs attention. Match options by stable IDs rather than display labels, especially where names are duplicated.

Validate the relationship again when saving

A correct options list is not the persistence boundary. The server must confirm that the submitted child belongs to the submitted parent and is available within the caller's scope. Database relationship constraints matter too: two individually valid foreign keys do not necessarily prove that their combination is permitted.

Test normal changes, rapid A-to-B requests, no options, a failed load, existing-record hydration and a manually altered request. The feature is complete when it rejects an invalid relationship as reliably as it displays a valid one.

Preventing stale response updates; Modeling persistent relationships.

✳ You have reached the end of this orbit.
Explore more articles →
turgay.A little code, a few pixels, a lot of curiosity.© 2026 · Made on Earth ✳