-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Description
When using built-in Vendure relation selectors in single-select mode (e.g., SingleRelationInput with customerRelationConfig as shown in the official docs), clicking the × (remove) button triggers onChange(undefined). However, undefined is not serialized in JSON and is ignored by Vendure’s GraphQL API, causing the previously selected value to persist on the server after form submission.
To Reproduce
- Use the documented example:
import { customerRelationConfig, SingleRelationInput, DashboardFormComponent, CustomFormComponentInputProps, // not imported } from '@vendure/dashboard'; export function CustomerSingleSelector({ value, onChange }: DashboardFormComponent) { return <SingleRelationInput value={value} onChange={onChange} config={customerRelationConfig} />; }
- Select a customer.
- Click × to clear the selection.
- Submit the form.
- Refresh — the old value is restored.
Expected Behavior
After clearing, onChange(null) should be called (not undefined), so the payload includes "customerId": null, and the relation is properly unset on the server.
Actual Behavior
onChange(undefined) is called → field disappears from JSON payload → server retains the old value.
Root Cause
The internal RelationSelector component (used by SingleRelationInput) calls onChange(undefined) in handleRemove for multiple: false. This is incompatible with Vendure’s expected input shape for optional relations (ID → string | null, not undefined).
Workaround
Wrap onChange to convert undefined → null:
export function CustomerSingleSelector({ value, onChange }: DashboardFormComponent) {
return (
<SingleRelationInput
value={value}
onChange={newValue => {
onChange(newValue ?? null); // ✅ Ensures null is passed
}}
config={customerRelationConfig}
/>
);
}Suggested Fix
Update RelationSelector (and/or SingleRelationInput) so that in single-select mode, handleRemove calls onChange(null) instead of onChange(undefined). This aligns with GraphQL conventions and ensures clean interoperability with Vendure core.
Impact
Affects all built-in and custom single-select relation components (productRelationConfig, collectionRelationConfig, etc.) wherever multiple: false is used.