diff --git a/CHANGELOG.md b/CHANGELOG.md index 06feda2166..6e4ef71908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## Fixed - [#3395](https://github.com/plotly/dash/pull/3395) Fix Components added through set_props() cannot trigger related callback functions. Fix [#3316](https://github.com/plotly/dash/issues/3316) +- [#3397](https://github.com/plotly/dash/pull/3397) Add optional callbacks, suppressing callback warning for missing component ids for a single callback. ## [3.2.0] - 2025-07-31 diff --git a/dash/_callback.py b/dash/_callback.py index df3176ece1..663401e3f3 100644 --- a/dash/_callback.py +++ b/dash/_callback.py @@ -77,6 +77,7 @@ def callback( cache_args_to_ignore: Optional[list] = None, cache_ignore_triggered=True, on_error: Optional[Callable[[Exception], Any]] = None, + optional: Optional[bool] = False, **_kwargs, ) -> Callable[..., Any]: """ @@ -159,6 +160,8 @@ def callback( Function to call when the callback raises an exception. Receives the exception object as first argument. The callback_context can be used to access the original callback inputs, states and output. + :param optional: + Mark all dependencies as not required on the initial layout checks. """ background_spec = None @@ -213,6 +216,7 @@ def callback( manager=manager, running=running, on_error=on_error, + optional=optional, ) @@ -258,6 +262,7 @@ def insert_callback( running=None, dynamic_creator: Optional[bool] = False, no_output=False, + optional=False, ): if prevent_initial_call is None: prevent_initial_call = config_prevent_initial_callbacks @@ -281,6 +286,7 @@ def insert_callback( }, "dynamic_creator": dynamic_creator, "no_output": no_output, + "optional": optional, } if running: callback_spec["running"] = running @@ -624,6 +630,7 @@ def register_callback( dynamic_creator=allow_dynamic_callbacks, running=running, no_output=not has_output, + optional=_kwargs.get("optional", False), ) # pylint: disable=too-many-locals diff --git a/dash/dash-renderer/src/actions/dependencies.js b/dash/dash-renderer/src/actions/dependencies.js index 63c9440fb2..657647da7e 100644 --- a/dash/dash-renderer/src/actions/dependencies.js +++ b/dash/dash-renderer/src/actions/dependencies.js @@ -570,12 +570,18 @@ export function validateCallbacksToLayout(state_, dispatchError) { for (const id in map) { const idProps = map[id]; const fcb = flatten(values(idProps)); - const optional = all( - ({allow_optional}) => allow_optional, - flatten( - fcb.map(cb => concat(cb.outputs, cb.inputs, cb.states)) - ).filter(dep => dep.id === id) - ); + const optional = fcb.reduce((acc, cb) => { + if (acc === false || cb.optional) { + return acc; + } + const deps = concat(cb.outputs, cb.inputs, cb.states).filter( + dep => dep.id === id + ); + return ( + !deps.length || + all(({allow_optional}) => allow_optional, deps) + ); + }, true); if (optional) { continue; }