UI5
No Comments

Why sap.ui.getCore().byId() Returns Undefined in SAP UI5?

Two glowing question marks surrounded by not glowing question marks.

sap.ui.getCore().byId() returns undefined when it could not find a control with the to sap.ui.getCore().byId() passed ID. For example, sap.ui.getCore().byId(“bar”) returns undefined if the SAP UI5 application does not contain a control with the set ID bar.

But what if there is actually in an XML view a control with an set ID of bar like:

<!-- in your XML view -->

<mvc:View 
    id="foo"
    controllerName="my.app.controller.FooController" 
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m">

        <Button id="bar" text="Click this"/>

<mvc:View>

And in the controller of the view is in the onAfterRendering() hook a
sap.ui.getCore(“bar”). But it returns undefined.

// in your controller 

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function (Controller) {
    "use strict";

    return Controller.extend("my.app.controller.FooController", {

        onAfterRendering: function() {
            
            // returns undefined
            var oButton = sap.ui.getCore().byId("bar");

            // works
            oButton = this.byId("bar");

        }

    });

});

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

First of all, this.byId(); is the way to get a control from a view in its controller. But what if you would like to get in a controller a control from another view then the controller’s view? Because this.byId() can only get controls from the view which is assigned to the controller.

The first assumption would be to use sap.ui.getCore().byId(“bar”) with bar for the id property of the control from the other controller. But that does not work. And here is why:

IDs of Controls Are Prefixed with the IDs of Its Views in SAP UI5

The views prefix the control IDs with its own IDs. This has the advantages of that

  1. the same control ID can be used in different views. For example, the ID foo for a button control could be used in View1 and in View2.
  2. the same view can be used multiple times. For example, if the view is nested in another view or reused in the application.

To avoid ID collisions of controls, each view adds its own ID as a prefix to all its child controls. For example, a view has the ID foo. A button control in the view has the ID 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.

And this is the difference of this.byId() and sap.ui.getCore().byId(): A view’s byId() adds the prefix of the view automatically to the requested ID which is passed as argument to the method. But sap.ui.getCore().byId() does not add any prefix.

Behind the scenes this.byId() calls sap.ui.getCore().byId(). But this.byId() puts the argument this.createId(id) into sap.ui.getCore().byId(): sap.ui.getCore().byId(this.createId(id)). id is the String argument from byId().

For example, “bar” in byId(“bar”): The method createId() of the controller takes the ID of the controller’s view and prefixes it to the passed ID from byId(). Hence, this.byId(“bar”) calls behind the scenes sap.ui.getCore().byId(this.createId(id)) and ends up in sap.ui.getCore().byId(“foo–bar”):

// this is what this.by.Id() calls 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() works only with the view prefix or nested views prefixes of the control added to the control’s ID. But in contrast to this.byId() works sap.ui.getCore().byId() for controls too that are in other views then the controller’s view.

<!-- in your XML view foo -->

<mvc:View 
    id="foo"
    controllerName="myApp.controller.FooController" 
    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>
// in your controller of foo view

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function (Controller) {
    "use strict";

    return Controller.extend("myApp.controller.FooController", {
        onAfterRendering: function() {
            
            // looks for ID foo--bar
            // works
            var oButton = this.byId("bar");

            // looks for ID bar
            // returns undefined
            oButton = sap.ui.getCore().byId("bar");

            // looks for ID foo--bar
            // works
            oButton = sap.ui.getCore().byId("foo--bar");

        }

    });

});
// in your controller of another view than foo

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function (Controller) {
    "use strict";

    return Controller.extend("myApp.controller.BarController", {
        onAfterRendering: function() {
            
            // looks for ID bar--bar
            // returns undefined
            var oButton = this.byId("bar");

            // looks for ID bar
            // returns undefined
            oButton = sap.ui.getCore().byId("bar");

            // looks for ID foo--bar
            // works
            oButton = sap.ui.getCore().byId("foo--bar");

        }

    });

});

Nested Controls Require Multiple Prefixes and How to Deactivate Auto Prefixing

If a control is nested in multiple views or further controls then it is necessary to prefix the IDs of those controls as well. For example, a view with the ID foo contains a simple form with the ID bar and the form contains an input with the ID input1. Then the ID of the input would be foo–bar—input1.

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

// manifest.json

...

sap.ui5 {

    ...

    autoPrefixId: false

}

...

However, this is not recommended.

Most Recent Articles

Will SAP UI5 replace the SAP Web UI?

SAP Full Forms

More Similar Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu