sapui5

`this` is not the controller in an event handler assigned from JSView


I have recently started with UI5, and am stuck with routing between views. I am able to route between two XML views & from XML view to JS view. However, I am not able to navigate away from a JS view.

The first view is loaded but when routing to the second view, the message on console is:

Uncaught TypeError: Cannot read property 'navTo' of undefined".

The method sap.ui.core.UIComponent.getRouterFor(this) returns undefined.

Component.js:

sap.ui.define([
  "sap/ui/core/UIComponent",
  "sap/ui/Device",
  "sapui5/app53/model/models"
], function(UIComponent, Device, models) {
  "use strict";

  return UIComponent.extend("sapui5.app53.Component", {
    metadata: {
      manifest: "json"
    },

    init: function() {
      UIComponent.prototype.init.apply(this, arguments);
      this.setModel(models.createDeviceModel(), "device");
      this.getRouter().initialize();
    }

  });
});

Routing part of manifest.json:

{
  "config": {
    "viewType": "JS",
    "viewPath": "sapui5.app53.view",
    "targetControl": "idPageContainer",
    "targetAggregation": "pages",
    "routerClass": "sap.m.routing.Router"
  },
  "routes": [
    {
      "pattern": "",
      "name": "First",
      "view": "zjs_view_53_02",
      "targetAggregation": "pages"
    },
    {
      "pattern": "second",
      "name": "Second",
      "view": "zjs_view_53_03",
      "targetAggregation": "pages"
    }
  ]
}

Container view:

sap.ui.jsview("sapui5.app53.view.zjs_view_53_01", {
  getControllerName: function() {
    return "sapui5.app53.controller.zjs_view_53_01";
  },

  createContent: function(oController) {
    this.setDisplayBlock(true);
    return new sap.m.App("idPageContainer");
  }

});

First View:

sap.ui.jsview("sapui5.app53.view.zjs_view_53_02", {
  getControllerName: function() {
    return "sapui5.app53.controller.zjs_view_53_02";
  },

  createContent: function(oController) {
    var oButton = new sap.m.Button({
      id: "idButton1",
      text: "Go to Next View",
      press: [oController.onNextView]
    });
    return new sap.m.Page({
      title: "Title Page 2",
      content: [
        oButton
      ]
    });
  }

});

Controller for first View:

sap.ui.controller("sapui5.app53.controller.zjs_view_53_02", {
  onNextView: function() {
    var router = sap.ui.core.UIComponent.getRouterFor(this);
    return router.navTo("Second", null); // Error
  }
});

Solution

  • Update: JS View is deprecated since UI5 v1.90. Use Typed View instead.


    In JSView or whenever assigning a handler to an event, make sure to always pass the listener object (oController) if needed:

    var oButton = new sap.m.Button({
      id: this.createId("idButton1"),
      text: "Go to Next View",
      press : [oController.onNextView, oController],
    });

    In the handler, the this will be then your controller instance which allows accessing the router from there.

    To learn more: