skip to content

A field's option list depends on another field's value: what must happen to the dependent field when the parent changes?

level: seniorimportance: should knowfreq 52%

answer

  1. the child does not know the parent changed
  2. membership is a rule you write
  3. reset the whole chain, not one level
  4. pending is a third state
  5. hydration must not fire the cascade

basics

~20 s

Reset the dependent value against the new option set, clear its error and touched flag, cascade the same reset down the chain, and show a loading or empty state — otherwise a value missing from the new list still submits.

solid answer

~40 s

Nothing in the model knows that a stored value has stopped being a legal choice. When the parent changes, the dependent value stays as it was while its control renders from the new option list and shows nothing — so what the user sees and what will be submitted disagree. The parent's change handler owns a cascade: **reset the dependent value**, **clear its verdict and touched flag** so it is not blank and red at once, and **repeat down the chain**, because a third level depends on the second. While the new options are in flight the field has a third state that is neither valid nor invalid: render it as loading and block advancing, rather than failing a membership rule against a list that does not exist yet.

go deeper

for a junior

Recall that changing the parent field does not clear the dependent one by itself. Its value has to be reset explicitly, along with its error, before the new option list arrives.

for a middle

Explain why the stale value still submits, that membership is a rule you have to write, and that the reset covers the value, the verdict and the touched flag together.

for a senior

Demonstrate the full cascade down every level, the pending third state distinguished from an empty set, and the hydration order for an existing record — including not firing the cascade while seeding.

for a principal

Decide the policy once for the whole form language: how dependency is declared, how far a reset propagates, and how pending dependent sets gate submission, so every screen behaves the same way.

## The shape of the dependency One field's legal values are a function of another's: a region list per country, a model list per manufacturer, a seat map per travel class. Structurally it is a parent field, a derived option set, and a dependent field whose value must be a member of that set. The dependent field therefore has two pieces of state, not one — **its value** and **the set it is a member of** — and only the first is under the user's finger. ## Why a stale value survives The model stores a value at a path. Nothing in that storage references the option list, so changing the parent does not touch it. Three consequences follow, and candidates who have not lived through this name only the first: - The dependent control renders from the new list and finds no matching entry, so it shows blank or falls back to a placeholder. - The model still holds the old value, so **submission sends a choice the user cannot see and did not make**. - Any stored verdict for that field is also unchanged, so a field that was previously valid stays "valid" while holding an illegal value, and one that was invalid stays red for a reason that no longer applies. Membership in the option set is a **rule you must write**. It is not a property the form derives, which is why "the value becomes invalid automatically" is the most expensive wrong assumption in this area. ## The reset is a cascade When the parent changes, in one update: 1. Reset the dependent value — to empty, or to the sole member if the new set has exactly one, or keep it only when the new set is already in hand and still contains it. 2. Clear the dependent field's verdict and its touched flag, so it presents as fresh rather than as failed. 3. Apply steps 1 and 2 to **every level below**, not just the immediate child. A country change invalidates region *and* city; leaving the grandchild is the classic half-fix. 4. Request the new option set for the immediate child only. Deeper levels have no meaningful request until their own parent has a value again. The same logic applies inside a repeating group, one chain per row, addressed by that row's path — which is why the reset must be expressed over paths rather than over named fields. A few habits keep the cascade honest: - express the reset over **paths**, so the same code serves one chain or one chain per repeating row; - reset the verdict and the flag with the value, never the value alone; - request a set only for the level whose parent now has a value; - treat "exactly one member" as a policy decision — auto-select it, or still make the user choose. ## Loading and empty are states, not verdicts Between the parent's change and the arrival of the new set, the dependent field can answer neither "valid" nor "invalid", and treating it as either produces a bad screen: | Situation | Wrong handling | What the user should get | |---|---|---| | Options in flight | membership rule fails | loading affordance, control disabled, advancing blocked | | Options arrived empty | "required" error | a stated "no options for this choice" message | | Options failed to load | field silently blank | an error about the load, with a retry | So the dependent field's rule has to distinguish "no value yet" from "a value that is not a member", and treat "set unknown" as a pending condition that suppresses the verdict while still preventing submission. ## Hydrating an existing record Editing an existing record inverts the order. The stored child value is legal, but it cannot be validated — or even rendered as selected — until the set implied by the stored parent value is loaded. Seeding the whole model at once and validating immediately reports a false error on a field that is perfectly correct. The reliable sequence is: seed both values, mark the dependent field pending, load the set implied by the parent, then let the membership rule run. And crucially, hydration must **not** run the parent's change cascade, or seeding the form wipes the very value it was seeding. ## What is deliberately not this problem Whether two overlapping option requests can resolve out of order — and how the later-issued one wins — is an async-coordination question and has its own home. Likewise, nothing here is about how a request is spelled. What belongs to the dynamic-form model is: which values are reset, which verdicts are cleared, how far the cascade reaches, and what the field's third state looks like. ## Interview shape Start from "the stored value does not know its option set changed", then give the cascade, then the pending state, then the hydration inversion. Mentioning the repeating-group case — one chain per row, keyed by the row's path — is what separates someone who has built this from someone who has read about it.

  • Why is clearing the immediate child not enough in a three-level chain?
    Because the third level's legality derives from the second, which no longer has a value. Leaving a city selected under a cleared region keeps an unreachable value in the model, and it submits. Each parent change resets every level below it, then only the next level's option set is requested.
  • What should the dependent field's rule do while its option set is still loading?
    Treat the set as unknown: suppress the membership verdict so the field is not falsely red, but keep the form from advancing or submitting while any dependent set is pending. Distinguish that from an arrived-but-empty set, which is a real condition the user needs told in words rather than as a required error.
  • How do you seed this pair of fields when editing an existing record?
    Seed both values without running the parent's change cascade, mark the dependent field pending, load the set implied by the seeded parent, then validate. Running the cascade during hydration clears the stored child value, and validating before the set arrives reports an error against a value that is actually legal.

saying these in an interview costs you the question

  • Assumes a stored value becomes invalid on its own when options change
  • Clears only the immediate child and leaves lower levels stale
  • Runs a membership rule against an option set not yet loaded
  • Keeps the old verdict after resetting the dependent value
  • Shows a required error when the new option set comes back empty
  • Fires the parent cascade while seeding an existing record