Show UI toasts while a button click in progress

How to do something like following? I need to show a notification in between method calls.

@Subscribe
public void onBeforeSave(final BeforeSaveEvent event) {
  notifications.show("Step 1 in progress");
  step1();
  notifications.show("Step 2 in progress");
  step2();
  notifications.show("Step 3 in progress");
  step3();
}

Hello,

Maybe something like this?

https://demo.jmix.io/ui-samples/sample/progress-bar-simple

Kind regards,
Mladen

https://demo.jmix.io/ui-samples/sample/background-task-dialog?tab=Description

Hi,

Mladen is right, a background task / background task dialog is the right approach here.

The reason is that notifications will not be shown in the browser in the middle of one synchronous server-side request. In your example the UI is busy until onBeforeSave() is finished, so the user will normally see the result only after all steps are completed.

For this case I would move the long-running logic to a BackgroundTask and publish progress between steps. UI updates should be done in progress() / done(), not inside run().

A simplified example:

@Autowired
private BackgroundWorker backgroundWorker;

@Autowired
private Notifications notifications;

@Subscribe("startButton")
public void onStartButtonClick(ClickEvent<Button> event) {
    BackgroundTask<Integer, Void> task = new BackgroundTask<>(5, TimeUnit.MINUTES, this) {

        @Override
        public Void run(TaskLifeCycle<Integer> taskLifeCycle) throws Exception {
            taskLifeCycle.publish(1);
            step1();

            taskLifeCycle.publish(2);
            step2();

            taskLifeCycle.publish(3);
            step3();

            return null;
        }

        @Override
        public void progress(List<Integer> changes) {
            Integer step = changes.get(changes.size() - 1);
            notifications.show("Step " + step + " in progress");
        }

        @Override
        public void done(Void result) {
            notifications.show("Done");
        }
    };

    backgroundWorker.handle(task).execute();
}

If the user has to wait until the operation is finished, I would prefer dialogs.createBackgroundTaskDialog(task) instead of only showing several toast notifications. It gives better feedback and can also show progress/cancel action if needed.

Also, I would avoid running long operations directly inside BeforeSaveEvent. Usually it is better to move this to a custom button/action handler, run the background task, and save the entity after the task is completed.

Docs:

And as an additional note: for small code examples like this, Jmix AI Assistant can be quite useful. You can ask it to generate a BackgroundTask or background task dialog example for your specific screen and then adjust it to your business logic.

Regards,
Dmitry