Skip to content

dashboard: Single relation selectors fail to clear: onChange(undefined) should be onChange(null) #4032

@dvjeshka

Description

@dvjeshka

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

  1. 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} />;
    }
  2. Select a customer.
  3. Click × to clear the selection.
  4. Submit the form.
  5. 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 (IDstring | null, not undefined).

Workaround

Wrap onChange to convert undefinednull:

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.


Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions