Skip to content

Choosing

Many workflows deliver one of several versions: the voice-over in the customer’s language, the care note for the product’s category, the layout for the format a channel asks for. The version is chosen by a key that arrives with the run — a language code, a category, a format name — and the node that makes the choice is Select by Key (utility/select_by_key). Like the nodes in Deciding, it is deterministic and costs nothing.

There are two ways to use it, and the difference is what runs:

  • Pick — every version is produced, and Select by Key keeps one. Simple, and right when the versions are cheap or all of them are useful.
  • Route and rejoin — a Filter per version lets only the chosen branch run, and Select by Key rejoins the branches. Right when each version costs credits: the versions not chosen are never made.

Its configuration, Selection (selectionConfig), declares:

Field Meaning
valueType the type of the values it chooses between: text, number, boolean, json, image, video, audio, url, document or model3d — one type for every case
cases one to sixteen cases, each a key (what the selector must match), an inputPort (the name of the input that receives that case’s value) and an optional label
caseSensitive whether IT and it are different keys; off by default
onNoMatch what happens when the selector matches no key: use_default, absent or fail

Each case becomes an input of the node, typed with the value type, and the Selector (selector) input receives the key. The selector must be a text — a number or a boolean is refused, not converted — and surrounding spaces are ignored. Read it with Extract when it is a field of the data.

The node answers with the chosen value on Selected Value (selected_value), and three outputs that say how it chose: selected_key (the key that matched, or default), matched and used_default.

When the selector matches no key:

onNoMatch Result
use_default the value connected to Default Value (default_value) is used; matched is false, used_default is true
absent selected_value and selected_key are rejected: what follows is skipped, and the run still completes
fail the node fails with SELECTOR_NO_MATCH — right when an unknown key is a mistake in the data that someone must fix

Choose the behaviour that says what an unknown key means. A language nobody translated into can fall back to English; a category the catalogue does not know should probably not produce anything; a format code that must exist is an error.

In the pick pattern every case is connected to a producer, every producer runs, and Select by Key keeps one value. The choosing lab writes a thank-you message in English, Italian and French with three Templates and picks one by a language code, with the English message also connected to Default Value.

The lab, left to right: the customer name and the language; three Templates, in English, Italian and French; Pick by language, with the French message chosen

Language Message selected_key used_default
FR Merci pour votre commande, Giulia Ferri ! fr false
de Thank you for your order, Giulia Ferri! default true

FR matches the key fr because the match ignores case. de has no case, so the default applies.

Terminal window
node madoo-install-example.mjs lab-choosing --api <your Madoo API URL> --key <key.json> --run

The second run is in run-inputs-no-match.json.

Picking is right for three Templates; it is wasteful for three AI voice-overs, because every one of them is made and paid for. That is what routing is for.

In the route pattern each version has its own branch, and each branch starts with a Filter whose condition is a Predicate comparing the key with that branch’s key (equals). Exactly one Filter passes; the others reject, and their branches are skipped — however many steps they have, and at no cost. Select by Key, fed with the same key, rejoins the branches: it accepts the rejected cases, so only the chosen one has to arrive.

The routing lab writes a care note by product category. It reads the name and the category from the product; three Predicates and three Filters route the name to the lamp, chair or textile branch; Select by Key rejoins them by the category, with onNoMatch: absent.

The lab, top to bottom: the product; the name and the category; a Predicate and a Filter per category; the three care notes, with the lamp and textile notes skipped; Rejoin by category, with the chair note chosen

Product Branches that ran Care note
Oak chair, chair chair only; lamp and textile skipped (branch_rejected) Care for Oak chair: wipe with a dry cloth; oil the wood once a year.
Velvet sofa, sofa none absent — no key matches, and every branch was rejected

Both runs complete in a few seconds at no cost.

Terminal window
node madoo-install-example.mjs lab-routing --api <your Madoo API URL> --key <key.json> --run

Keep the two comparisons in step. A Predicate equals compares texts exactly, case included; Select by Key ignores case unless caseSensitive is on. The lab turns it on, so that a category written Chair matches neither a Filter nor a case, and the note is simply absent. Without it, the rejoin would choose the chair case whose branch no Filter let through — and the note would be absent too, but for a less obvious reason.

You need Use
one of two branches, by a condition two Filters, one inverted — see Deciding
the key decided from content — the team of a message, the kind of a document, the best of several pictures a choice of Decide with a Model on the selector
one of several values, all cheap to produce Select by Key alone
one of several branches, each with a cost a Predicate and a Filter per branch, rejoined by Select by Key
an optional step, on or off a Boolean Input and a Filter — see Branches and absence

The older Image Switch (control/image_switch) chooses among images by a label. It still works in the workflows that use it; for a new workflow, use Select by Key with valueType: image, which also handles every other type.

Code Cause Fix
INVALID_SELECTION_CONFIG the selection is incomplete: an unsupported type, a duplicate key or input name, no cases or more than sixteen fix the configuration the message points to
MISSING_SELECTOR nothing reached Selector connect the key
INVALID_SELECTOR_TYPE the selector is not a text pass a text; read it with Extract and expected_type: text
SELECTOR_NO_MATCH no key matches and onNoMatch is fail add the case, or choose use_default or absent
MISSING_SELECTED_VALUE the matching case has no connection connect a value to every case
MISSING_DEFAULT_VALUE no key matches, onNoMatch is use_default, and nothing reached Default Value connect the default
SELECTED_VALUE_TYPE_MISMATCH the chosen value does not have the configured type connect values of valueType only