OnCRUDBuilder constructor

OnCRUDBuilder({
  1. Key? key,
  2. required InjectedCRUD listenTo,
  3. Widget onWaiting()?,
  4. Widget onError(
    1. dynamic,
    2. void ()
    )?,
  5. required Widget onResult(
    1. dynamic
    ),
  6. void dispose()?,
  7. String? debugPrintWhenRebuild,
})

To listen to an InjectedCRUD state just use ReactiveStatelessWidget, OnReactive, or OnBuilder widgets.

Nevertheless, as the CREATE, UPDATE, DELETE functions can be performed optimistically, the user will not notice anything. Looks like he's dealing with a simple sync list of items.

If we want to show the user that something is happening in the background, we can use the OnCRUDBuilder widget.

OnCRUDBuilder<T>(
  listenTo: products,
  onWaiting: ()=> Text('onWaiting'),
  onError: (err, refreshErr)=> Text('onError'),
  onResult: (result)=> Text('onResult'),
)
  • onWaiting: while the database is querying.
  • onError: if the query ends with an error. IT exposes a refresher to reinvoke the async call that caused the error.
  • onResult; if the request ends successfully. It exposes the result fo the query (ex: number of rows updated).

OnCRUDBuilder vs OnBuilder.all or OnBuilder.orElse:

  • Both used to listen to injected state.
  • In pessimistic mode they are equivalent.
  • In optimistic mode, the difference is in the onWaiting hook.
    • In OnBuilder.all the onWaiting in never called.
    • In OnCRUDBuilder the onWaiting is called while waiting for the backend service result.
  • OnBuilder.all has onData callback.
  • OnCRUDBuilder has onResult callback that exposes the return result for the backend service.

Implementation

OnCRUDBuilder({
  Key? key,
  required this.listenTo,
  this.onWaiting,
  this.onError,
  required this.onResult,
  void Function()? dispose,
  String? debugPrintWhenRebuild,
}) : super(
        key: key,
        observers: (context) {
          return [(listenTo as InjectedCRUDImp).onCrudRM];
        },
        dispose: (_, __) {
          dispose?.call();
          listenTo.disposeIfNotUsed();
        },
        debugPrintWhenRebuild: debugPrintWhenRebuild,
        builder: (context, snap, rm) {
          final inj = rm as ReactiveModelImp;
          if (inj.isWaiting) {
            return onWaiting?.call() ?? onResult(inj.snapValue.data);
          }
          if (inj.hasError) {
            // Widget? w;
            // if (inj.hasError) {
            //   w = onError?.call(
            //     inj.error,
            //     inj.snapValue.snapError!.refresher,
            //   );
            // } else {
            //   w = onError?.call(
            //     inj.error,
            //     inj.snapValue.snapError!.refresher,
            //   );
            // }
            return onError?.call(
                  inj.error,
                  inj.snapValue.snapError!.refresher,
                ) ??
                onResult(inj.snapValue.data);
          }
          return (onResult(inj.snapValue.data));
        },
      );