sapui5tutors SAPUI5 • Fiori • SAP BTP Step-by-step tutorials Real project examples Interview Q&A
Practical SAPUI5 • Fiori • SAP BTP tutorials and interview prep

SAPUI5 Message Handling: MessageManager Explained

MessageBox and MessageToast cover the quick stuff — a success here, a warning there. But real forms have validation errors, OData failures, and warnings that need to survive a round trip. That is what the MessageManager is for: one central registry for every message in your app.

What the MessageManager Does

Think of it as a mailbox. Controls and code push messages in; message-aware controls and a MessagePopover pull them out. Instead of each view managing its own error state, every message lives in one model that any view can bind to.

Registration is usually done once in the component:

// Component.js
init: function () {
  UIComponent.prototype.init.apply(this, arguments);
  sap.ui.getCore().getMessageManager().registerObject(this.getView(), true);
}

Passing true as the second argument registers the object and everything inside it — so the whole view, including child views and fragments, reports into the manager automatically.

Key takeaway: register once at a high level and every control beneath it feeds the same message model. No per-form wiring.


Adding Messages

Messages are sap.ui.core.message.Message objects with a type, a text, and a processor that knows where the message came from.

const oMessageManager = sap.ui.getCore().getMessageManager();
oMessageManager.addMessages(new Message({
  message: "Delivery date cannot be in the past",
  type: MessageType.Error,
  target: "/Orders(42)/DeliveryDate",
  processor: this.getView().getModel()
}));

The target ties the message to a specific property, which is what lets input fields highlight themselves. The processor is the model the target belongs to.


ValueState: Automatic Error Highlighting

Here is the part that saves the most code. When a message targets /Orders(42)/DeliveryDate and an sap.m.Input is bound to that path, the input automatically switches to ValueState.Error and shows the message text as its value state tooltip. Remove the message, and the field clears itself.

This works for validation you trigger yourself and for backend errors too — the OData models push server messages into the manager automatically when a request fails.


Showing Messages with the MessagePopover

Users need one place to see everything. The MessagePopover binds to the message model and groups messages by type:

onMessagePopoverPress: function (oEvent) {
  const oButton = oEvent.getSource();
  if (!this._oMessagePopover) {
    this._oMessagePopover = new MessagePopover({
      items: {
        path: "message>/",
        template: new MessageItem({
          title: "{message>message}",
          type: "{message>type}",
          description: "{message>description}"
        })
      }
    });
    this.getView().addDependent(this._oMessagePopover);
  }
  this._oMessagePopover.toggle(oButton);
}

A common pattern: a footer button showing the error count, bound to the message model with a filter on type. It only appears when there is something to show.

Key takeaway: bind the popover to the message> model and let the MessageManager be the single source of truth — never maintain a parallel error array.


Cleanup and Validation Flows

Messages do not expire on their own. Clear them deliberately — before a new validation run, or when the user navigates away:

oMessageManager.removeAllMessages();

A typical save flow: clear old messages, run client-side validation and add messages for failures, call submitChanges, and let backend errors arrive through the same manager. The popover and the field highlighting handle the rest, with zero custom error plumbing.

Say you have a three-step wizard with validation on each step: one MessageManager, one popover, and each step only adds and clears its own targets. That is the whole architecture.

Do you still reach for MessageBox first, or has the MessageManager replaced it in your projects? Let me know in the comments.