Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
rileyrainey
Product and Topic Expert
Product and Topic Expert
635
A while back, I wrote a couple of posts describing a method for avoiding issues rooted in Approuter session expiration (here and here). This is just a short follow-up to point out an error that you might encounter while trying to insert the code from my articles into your own SAPUI5 project and how to resolve it.

A colleague contacted me the other day. He'd integrate the code from my articles but, when he ran the application, his main controller was encountering this error:
MainView.controller.js:25 Uncaught (in promise) TypeError: Cannot read property 'getRouter' of undefined
at f.onInit (MainView.controller.js:25)
at f.b.fireEvent (EventProvider-dbg.js:247)

executeModuleDefinition @ ui5loader-dbg.js:1803

It turns out that the code that I used as an example was originally created from the standard Web IDE Master Detail Fiori application template. That template implements the informal BaseController design pattern.  His code had no BaseController, hence the problem.

The idea behind the pattern is to have a reusable controller class. All the view controllers then derive from BaseController to pick up several useful functions -- including, in this case, getRouter().

I'll include a copy of the BaseController.js I used below in case you'd like to use it yourself.  It turns out that many of the functions supplied by BaseController are fairly simple -- if you are more lazy, you might be inclined simply to copy and replace the getRouter() call with the equivalent function body.  Your choice.

Here's what BaseController.js looks like in our application.  If you do plan to insert this module into your project, don't forget to replace our application class prefix, "com.sap.TDash", with your project's identifier in the "extend" call:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/routing/History"
], function (Controller, History) {
"use strict";

return Controller.extend("com.sap.TDash.controller.BaseController", {
/**
* Convenience method for accessing the router in every controller of the application.
* @public
* @returns {sap.ui.core.routing.Router} the router for this component
*/
getRouter : function () {
return this.getOwnerComponent().getRouter();
},

/**
* Convenience method for getting the view model by name in every controller of the application.
* @public
* @param {string} sName the model name
* @returns {sap.ui.model.Model} the model instance
*/
getModel : function (sName) {
return this.getView().getModel(sName);
},

/**
* Convenience method for setting the view model in every controller of the application.
* @public
* @param {sap.ui.model.Model} oModel the model instance
* @param {string} sName the model name
* @returns {sap.ui.mvc.View} the view instance
*/
setModel : function (oModel, sName) {
return this.getView().setModel(oModel, sName);
},

/**
* Convenience method for getting the resource bundle.
* @public
* @returns {sap.ui.model.resource.ResourceModel} the resourceModel of the component
*/
getResourceBundle : function () {
return this.getOwnerComponent().getModel("i18n").getResourceBundle();
},

/**
* Event handler for navigating back.
* It there is a history entry we go one step back in the browser history
* If not, it will replace the current entry of the browser history with the master route.
* @public
*/
onNavBack : function() {
var sPreviousHash = History.getInstance().getPreviousHash();

if (sPreviousHash !== undefined) {
history.go(-1);
} else {
this.getRouter().navTo("master", {}, true);
}
}

});

}
);

If you are interested in digging more deeply into the BaseController pattern, you can find a discussion and more detailed example of its usage in this section of the OpenUI5 documentation.