SAPUI5: Why Does sap.ui.getCore().byId() Return Undefined?

This is why sap.ui.getCore().byId() might return undefined in SAPUI5.

The reason is how the SAPUI5 framework assigns IDs to controls.

You’ll learn:

  • Why sap.ui.getCore().byId() might return undefined
  • How to get the control anyway

Let’s get started!

Why Does sap.ui.getCore().byId() Return Undefined?

sap.ui.getCore().byId() returns undefined if it doesn’t find a control with the ID passed to sap.ui.getCore().byId().

For example, sap.ui.getCore().byId(“foo”) returns undefined if the SAPUI5 application does not contain a control with foo for the propery id.

But what if there was a control in an XML view that had an id property foo like:

<!-- in your XML view -->
 
<mvc:View
  id="view-1"
  controllerName="my.app.controller.View1"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m">
 
    <Button id="foo" text="Click this"/>
 
<mvc:View>

And in the view’s controller is in the onAfterRendering() method an sap.ui.getCore().byId(“foo”). But it returns undefined. However, this.byId(“foo”) works just fine:

// in your controller 
 
sap.ui.define([
  "sap/ui/core/mvc/Controller"
], function (Controller) {
  "use strict";
 
  return Controller.extend("my.app.controller.View1Controller", {
 
    onAfterRendering: function() {
             
      // returns undefined
      var oButton = sap.ui.getCore().byId("bar");
 
      // works
      oButton = this.byId("bar");
 
    }
 
  });
 
});

Why does sap.ui.getCore.byId(“bar”) not get the button with the id property foo?

And why does this.byId(“foo”) work?

First of all, this.byId() is the way to get a control from a view in its controller.

But what if you want to get a control in a controller from another view than the controller’s view? Because this.byId() can only get controls from the view that was assigned to the controller.

First assumed is sap.ui.getCore().byId(“foo”), where foo is the id property of the control in the other view. But that just ’t work as seen above.

Here’s why:

IDs of Controls Are Prefixed with the IDs of Its Views in SAPUI5

The views prefix the control IDs with their own IDs.

To avoid ID collisions, each view adds its own ID as a prefix to all its child controls.

For example, a view has the id property foo.

A button control in the view has the id property bar. Then the prefix that the view add to each of its controls is foo—. Therefore, the ID of the button control of the view is foo—bar.

Furthermore, the application’s id is always prefixed. So app—-foo—bar is the end result.

And this leads us to the difference between this.byId() and sap.ui.getCore().byId():

The byId() method adds the prefix of the view to the id property passed as an argument to the method.

sap.ui.getCore().byId() doesn’t prefix anything.

Behind the scenes, this.byId() calls sap.ui.getCore().byId().

But this.byId() puts the argument this.createId(id) into sap.ui.getCore().byId(). This is what it looks like:

sap.ui.getCore().byId(this.createId(id))

The id in sap.ui.getCore().byId(this.createId(id)) stays the String argument from byId(id).

For example, the view has the id property foo and the control in question has the id property bar.

The createId() method takes the controller’s view id and the app id and prefixes them with the passed id from byId().

Therefore, this.byId(“foo”) calls sap.ui.getCore().byId(“foo”) behind the scenes and ends up being sap.ui.getCore().byId(“app—foo–bar”):

// this is what this.by.Id() does behind the scenes
 
View.prototype.byId = function(sId) {
 
    return sap.ui.getCore().byId(this.createId(sId));
 
};

To Use sap.ui.getCore().byId() the ID of the Control Needs to Be Prefixed

Therefore, sap.ui.getCore().byId() only works with the view prefix or nested views prefix of the control added to the control id. But sap.ui.getCore().byId() works for controls that are in other views besides the controller’s view too:

<!-- in your XML view -->
 
<mvc:View
  id="foo"
  controllerName="myApp.controller.Foo"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m">
 
    <!-- view id is foo -->
    <!-- button control id is foo--bar -->
    <Button 
      id="bar" 
      text="Click this"/>
 
<mvc:View>

Nested Controls Require Multiple Prefixes and How to Deactivate Auto Prefixing

If a control is nested in multiple views or further controls, the IDs of those controls must also be prefixed.

For example, an application with id app-1 contains a view with id view-1, the view contains a simple form with id form-1, and the form contains an input with id input-1. Then the ID of the input would be app-1—view–1-bar-1-input-1.

By the way, it’s possible to deactivate the prefixing of IDs in the manifest.json:

// in your manifest.json
...
 
sap.ui5 {
 
    ...
 
    autoPrefixId: false
 
}
 
...

However, this isn’t recommended.

Leave a Comment