0
votes

I have two controllers and one XML file. I want to call a function of the second controller from the first controller. The function is supposed to change the text of the xml file associated with the second controller.

This is how I'm calling the function of the second controller from the first:

sap.ui.controller("project.controller.one").set("pancakes");

This is the function in the second controller:

set: function (text) {
    alert(text);
    this.getView().byId("label0").setText(text);
}

The XML just has a Label with an id of label0.

I get the following error:

Uncaught TypeError: Cannot read property 'byId' of undefined

whenever I reach this line:

this.getView().byId("label0").setText(text)

However if I place this in the onInit of controller two:

this.getView().byId("label0").setText("bananas")

then the label will change to "bananas" with no error.

What am I missing?

1
console.log(this) in set, see if it looks like a controller. If it does, then getView() probably didn't work. Then check <mvc:view controllerName="project.controller.one" in the corresponding view. - JJPandari
have you tried sap.ui.getCore().byId()? - KristoffDT
why are you having logic in two controllers? - futu

1 Answers

2
votes

The method sap.ui.controller returns a new controller instance as described on the documentation:

If only a name is given, a new instance of the named controller class is returned.

So it likely returns a copy of the controller that is not associated with the view, and so it will not find it. The method itself is also deprecated, so I would not recommend using it in general on newer UI5 versions.

The preferred way of communicating between two controllers is to use the sap.ui.core.EventBus.

In the second controller you would first subscribe to an event in the onInit, and bind it to a function:

onInit: function() {
    sap.ui.getCore().getEventBus().subscribe("Controller2", "set", this.setFromEvent, this);
    // ....
}

The first and second parameter are the channel and event name, which you can freely choose. The third parameter is the method to be called, and the fourth will be used as the value of this inside that method.

In order to trigger the event, you can use the publish method of the EventBus in you other controller:

sap.ui.getCore().getEventBus().publish("Controller2", "set", { value: "pancakes" });

The first and second parameters are the channel and event names that correspond to your subscribe above. The third parameter is an object with data you can send, which you can freely choose.

Of course, you will also need to create the setFromEvent method in the second controller:

setFromEvent: function(sChannelId, sEventId, oData) {
    this.set(oData.value);
}

The parameters of this method correspond to the values passed to the publish method above.