Skip to Content
Author's profile photo Wouter Lemaire

OpenUI5 / SAPUI5 Communication between controllers – Using Publish and Subscribe from EventBus

Hi SAPUI5 Developers,

In a SAPUI5 application you have probably for every view a controller. In every controller you’ll have functions.

A good developer don’t want to write unnecessary code and reuse coding as much as possible 🙂 Therefore it can be useful to call functions from other controllers.

For example, this could be useful when you’re working with nested views. You could have for example a parent view that exists out of two sub views. In your sub views you want to use a function from you’re parent view.

But there could be a lot of other reason that you want to communicate between controllers.

Therefore SAPUI5 has the EventBus. The EventBus has two functions to set up a communication between controllers:

  • Subscribe

          This function will define an event listener for a specific event.

  • Publish

          This function will trigger a specific event

The publish function can be called from everywhere in the project for different events. If there is a subscribe function defined for the triggered event, then it will execute the event handler.

How to use this in your SAPUI5 project?

In my example I’m using a “Main” view that contains a Label, a Button and two sub views.

/wp-content/uploads/2015/10/img1_817102.png


In the controller of my “Main” view, I have a function to show a message box:


/wp-content/uploads/2015/10/img2_817109.png


This will result in the following:


/wp-content/uploads/2015/10/img3_817110.png


Now in the sub views I also add a Label and a Button.

SubView1:


/wp-content/uploads/2015/10/img4_817111.png

SubView2:

/wp-content/uploads/2015/10/img5_817112.png

Now I want to use the function of my “Main” view to show the information message from the sub views. Therefore I edit the controller of my “Main” view.

In the “onInit” I define two event listeners with the subscribe function, one for “SubView1” and another for “SubView2”. Both are using the same event handler. They also require a name and an event. I use the name of the view where the event will be fired and the name of the event.

/wp-content/uploads/2015/10/img6_817113.png

The event handler is the same function that is used for the “Press” event of the Button in the “Main” view. Therefore I have to change this function to make it work for both cases.

/wp-content/uploads/2015/10/img7_817114.png

I’ve defined event listeners for the buttons on my sub views. But I still need to trigger these events.

To trigger these events I used the publish function of the EventBus in the button press function.

Controller of SubView1:

/wp-content/uploads/2015/10/img8_817115.png

Controller of SubView2:

/wp-content/uploads/2015/10/img9_817116.png

I need to use the same name and event as in the subscribe function to trigger the event. It will only call the event handler if these parameters have a match. Additionally I also add parameter with some text.

This will give the following result:

Use the button on the “Main” view

/wp-content/uploads/2015/10/img10_817117.png

Press the button on sub view 1

/wp-content/uploads/2015/10/img11_817118.png

Press the button on sub view 2

/wp-content/uploads/2015/10/img12_817119.png

Important to know, use the unsubscribe function of the eventbus when your app is used in the Fiori Launchpad! Otherwise it will stop working correctly after the following actions:

  1. Open the Fiori Launchpad
  2. Go to your app
  3. Go back to the Fiori Launchpad
  4. Open your app a second time

This last step will subscribe your function a second time to the eventbus.This will lead to errors.

Add the unsubscribe in the onAfter function, example:


onExit:function(){

     var eventBus = sap.ui.getCore().getEventBus();

     eventBus.unsubscribe(“SubView1″,”ShowPopup”,this.onShowPopup,this);

}

Hopefully this is useful.

You can find the full project on Github:

https://github.com/lemaiwo/SAPUI5Eventing

Try out the result:

http://lemaiwo.github.io/SAPUI5Eventing/webapp/test/index.html

Kind regards,

Wouter

Assigned Tags

      24 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Robin Van Het Hof
      Robin Van Het Hof

      Great blog on a powerful yet (undeservedly) undervalued feature of UI5 🙂

      Author's profile photo Venkatachala C.K
      Venkatachala C.K

      useful blog thanks for sharing

      Author's profile photo Kedar Tingikar
      Kedar Tingikar

      Good one, help clear the concept of EventBus

      Author's profile photo Former Member
      Former Member

      I like it! Thank you for sharing. : )

      Author's profile photo Former Member
      Former Member

      Great, was looking for a short, simple explanation of this concept.

      Author's profile photo Wolfgang Pfeifer
      Wolfgang Pfeifer

      Hi Wouter,

      thanks for sharing. Great stuff! Question: I plan to use this for parameter handling during navigation. Will the following scenario work? I mark some entries in view1, take out the values, publish them to the EventBus, navigate to view2, go through onInit(), create subscription and want to use the values in view2. I am in doubt about that a little since view2 is not initialized, when values are published to the EventBus. Are they getting queued and the triggering event as well or will they be lost and the payload wont male it to view2 in this scenario?

      Thanks a lot in advance.

      best regards

      WPdat

      Author's profile photo Wouter Lemaire
      Wouter Lemaire
      Blog Post Author

      Hi Pfeifer,

      I wouldn't use this for sending parameters from one view to another. Therefore I would use routing parameters. If you're sending a full json object to the view I would suggest to use a temporary JSON model to store the json object.

      Kind regards,

      Wouter

      Author's profile photo Sijin Chandran
      Sijin Chandran

      I used temporary JSON model, reason being am using Router concepts for navigation.

      And passed and retrieved data using setModel() and getModel() methods respectively.

      Thanks for this suggestion.

      Regards,

      Sijin

      Author's profile photo Wolfgang Pfeifer
      Wolfgang Pfeifer

      Hi,

      thanks a lot. After I tried to use router parameters in navTo with sap.m.routing I observed, that the handed over object is not transmitted. It is not appearing in arguments of the routing event I caught on the receiving side. Strange. All examples I found so far working with rewritten router , means own router class implementations. I think I gonna solve the problem with more or less global JSON models which obviously survive context changes during navigation.

      best regards

      Wolfgang

      Author's profile photo Shivam Bedwal
      Shivam Bedwal

      Hello Wouter,


      I have a question regarding passing of data from one view to another view, using event bus subscription -

      Does this event bus publish and subscription works only in case of nested views. ?


      I need to pass data from one view to another which are not nested. View 2 is called from View 1, on press of a button, and these two views are not nested.


      Could you help me here ?


      Regards,

      Shivam.

      Author's profile photo Wouter Lemaire
      Wouter Lemaire
      Blog Post Author

      For passing data from one view to another view you should use dynamic routing. If it's a lot of data that you want to pass, you can create a JSON model in the component for Shared data. Fill this shared model before you navigate and read it in the second view.

      Kind regards,

      Wouter

      Author's profile photo nikhil bhalewar
      nikhil bhalewar

      Hi Lemaire,

       

      What is the best way to pass lots of data from one view to other view. If i pass the data using routing with params the data is all over visible in the url. If i use JSON Model in component the model is getting cleared if i refresh the page. can you suggest some alternate way to tackle this issue.

       

      Thanks

      Author's profile photo Oben Clifford Ngobeni
      Oben Clifford Ngobeni

      Useful post.

      Author's profile photo Mauricio Pinheiro Predolim
      Mauricio Pinheiro Predolim

      Hi! i tried to run on url below but it's not working...

       

      http://lemaiwo.github.io/SAPUI5Eventing/webapp/test/index.html

       

      Regards.

      Author's profile photo Wouter Lemaire
      Wouter Lemaire
      Blog Post Author

      It's back up and running!

      Author's profile photo Boghyon Hoffmann
      Boghyon Hoffmann

      I think it’s also worth mentioning that we can get event bus from the component

      myComponent.getEventBus()

      .. which is hooked to the lifecycle of the component rather than from the core. I.e.: When the component gets destroyed (which will be when the user navigates back to the launchpad), then its event bus is also gone –> No need to unsubscribe handlers on exit.

      This is also recommended by SAP for apps on FLP.

      Do not use the global event bus.

      Also this answer might be helpful for other readers to understand EventBus a bit more: https://stackoverflow.com/a/46186706/5846045

      Author's profile photo Former Member
      Former Member

      Hi,

      I want to reuse code from one controller in another controller using the EventBus. The problem is that when I register the event handler with "subscribe", it automatically calls the function and I don't want that. I only want to call the function when i publish the event.

      Author's profile photo Former Member
      Former Member

       

      ...I submitted the comment before my question, so here it is: Do you know how I can stop the subscription of the event to call the actual function?

      Thanks,

      Cristina

       

      Author's profile photo Wouter Lemaire
      Wouter Lemaire
      Blog Post Author

      Normally it shouldn't call the function on subscribe, only on publish. Are you sure you didn't add the brackets when defining your funtion in the subscribe?

       

      Author's profile photo Former Member
      Former Member

      Yes, that was it, I forgot the brackets and I didn't see them, it's like I was blind. Thanks!

      Author's profile photo Vineet Safaya
      Vineet Safaya

      Hi Wouter,

      Very Informative blog on the Important topic of how SAP UI5 Event Bus works.

      Issue - The qualty tests for the project fails with a medium priority saying - "Fiori Architectural Guidelines :: Channel is too generic to be used with the event bus in a shell environment, you should rather use your application identifier" - JS_GENERIC_BUS_USAGE.md. This error is coming for the code - "this.bus.publish("flexible", "setDetailPage")".

      Can you please let me know if there is any alternative for using - this.publish, considering I want my view to be lazy loaded as my app has more than 10 views. (specially while using Flexible Column Layout, since the explored example also uses event bus way of navigating and adding views.)

      Author's profile photo Wouter Lemaire
      Wouter Lemaire
      Blog Post Author

      Don't think you can do this with the eventbus. I thought views are only loaded the first time you request them... don't understand why you want to change this...

      Author's profile photo Cristian Borcea
      Cristian Borcea

      Thank you so much 🙂

      Author's profile photo Mukesh Dubey
      Mukesh Dubey

      Very Useful information!:)