TypeError: oRouter.getRoute(...) is undefined - sapui5

I am new to SAPUI5 and I would like to navigate to the details of an object on a second view, but I have an error:
TypeError: oRouter.getRoute (...) is undefined
Can someone help me?
Airport.controller.js
onInit: function() {
jQuery.sap.require("sap.m.ObjectAttribute");
jQuery.sap.require("sap.m.MessageBox");
var oList = this.getView().byId("List01");
oList.bindItems({
path: "JSON>/products",
template: new sap.m.StandardListItem({
type: "Navigation",
title: "{JSON>fields/aeroport}",
press: [this.onPress, this],
}),
});
},
onPress: function(oEvt) {
var oItem = oEvt.getSource();
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
var temp = oItem
.getBindingContext("JSON")
.getPath()
.substr(10);
oRouter.navTo("Detail", {
airportPath: temp,
});
},
Detail.controller.js
onInit: function() {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("detail").attachPatternMatched(this._onObjectMatched, this);
},
_onObjectMatched: function(oEvt) {
this.getView().bindElement({
path: "/products/" + oEvt.getParameter("arguments").airportPath,
model: "JSON",
});
},
Detail.view.xml
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
controllerName="SAPUI5CoolProject.controller.Detail"
>
<App id="Detail">
<Page
title="Airport Detail"
showNavButton="true"
navButtonPress="goBackOtherAirport"
>
<ObjectHeader title="{JSON>products/fields}"/>
</Page>
</App>
</mvc:View>
manifest.json
{
"pattern": "Detail/{airportPath}",
"name": "Detail",
"target": ["Detail"]
}

oRouter.getRoute("detail") → oRouter.getRoute("Detail")
Since the API getRoute awaits the name of the route defined in the app descriptor, and because JS is case-sensitive, the exact same string literal has to be passed as the argument.

Related

Unable to access control, created in JSView, from controller with View byId

I am trying to display a VizFrame and my data are in a simple JSON format.
Both my view and controller are in JS. (I will start writing my view in XML going forward) because I see that is the way to go.
I get a blank page with the error: "setDataset of undefined". What am I missing?
My view code is this.
createContent: function(oController) {
var oSubHeader = new sap.m.Bar({
contentLeft: [
new sap.m.Button({
icon: "sap-icon://nav-back",
press: [oController.onNavBack, oController]
})
],
contentMiddle: [
new sap.m.Label({
text: "{i18n>app_subhead_2}"
})
]
});
var oVizFrame = new sap.viz.ui5.controls.VizFrame("VizFrameId", {
width: "100%",
height: "400px",
vizType: "line"
});
var oPage = new sap.m.Page({
title: "UI5 Assignment App",
showSubHeader: true,
subHeader: oSubHeader,
content: [oVizFrame]
});
return oPage;
}
My corresponding controller is
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/UIComponent",
"sap/ui/core/routing/History",
"sap/viz/ui5/controls/VizFrame",
"sap/viz/ui5/data/FlattenedDataset"
], function (Controller, UIComponent, History, VizFrame, FlattenedDataset) {
"use strict";
return Controller.extend("Project_Tile_learning.Divya_tile_Project.controller.ProductDetailPage", {
onNavBack: function () {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("homepage", true);
}
},
onInit: function () {
var sampleDatajson = new sap.ui.model.json.JSONModel("json/PA.json");
var oVizFrame = this.getView().byId("VizFrameId");
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
name: "Year",
value: "{Year}"
}],
measures: [{
name: "Supplier",
value: "{Supplier}"
}, {
name: "Liquor",
value: "{Liquor}"
}, {
name: "Quantity",
value: "{Quantity}"
}],
data: {
path: "/items"
}
});
oVizFrame.setDataset(oDataset);
oVizFrame.setModel(sampleDatajson);
var oFeedValueAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Supplier"]
});
var oFeedValueAxis1 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Liquor"]
});
var oFeedValueAxis2 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Quantity"]
});
var oFeedCategoryAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "categoryAxis",
"type": "Dimension",
"values": ["Year"]
});
oVizFrame.addFeed(oFeedValueAxis);
oVizFrame.addFeed(oFeedValueAxis1);
oVizFrame.addFeed(oFeedValueAxis2);
oVizFrame.addFeed(oFeedCategoryAxis);
}
});
});
Update: JS View is deprecated since UI5 v1.90. Use Typed View instead.
When creating a control in JS view definition, always use this.createId("myControl").
From the doc:
If you want to define IDs for controls inside a JSView to guarantee their uniqueness [...], you cannot give hardcoded IDs, but have to give the view the opportunity to add its own instance ID as a prefix. This is done by using the View.createId(...) method.
For the example above, this is done as follows:
new sap.viz.ui5.controls.VizFrame(this.createId("VizFrameId"), { /*...*/ });
Then in the controller, myView.byId tries to access the control with view's own ID as a prefix, which will succeed this time since the control has an ID with the view ID as a prefix.

Uncaught (in promise) Error: The specified component controller could not be found

We have upgraded the sapui5 application from 1.44 to 1.56 version. My application was working properly in 1.44 version.
After upgrade it gives me below error.
"Uncaught (in promise) Error: The specified component controller 'com.test.ui.Component' could not be found!"
Note: Component.js is loaded successfully i.e no 404 error for Component.js
<script id="sap-ui-bootstrap"
src="../../../resources/sap-ui-core.js"
data-sap-ui-libs="sap.m, sap.me"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-compatVersion="1.16"
data-sap-ui-appCacheBuster="./"
data-sap-ui-resourceroots='{"com.test.ui": "./"}'></script>
<link rel="stylesheet" type="text/css" href="CSS/style.css" />
<script>
sap.ui.getCore().attachInitEvent(function() {
var oShell = new sap.m.Shell("idshell");
var oComponentContainer = new sap.ui.core.ComponentContainer({
height : "100%",
name : "com.test.ui"
});
oShell.setApp(oComponentContainer);
oShell.placeAt("content");
});
</script>
Component.js
jQuery.sap.declare("com.test.ui.Component");
jQuery.sap.require("sap.m.routing.RouteMatchedHandler");
sap.ui.define(["sap/ui/core/UIComponent"],function(UIComponent){
"use strict";
UIComponent.extend(
"com.test.ui.Component", {
metadata: {
"name": "com.test.ui",
"version": "1.0",
"includes": ["css/style.css"],
"dependencies": {
"libs": ["sap.m", "sap.ui.core", "sap.me",
"sap.ushell"
],
"components": []
},
"config": {
"resourceBundle": "i18n/messageBundle.properties",
"titleResource": "title",
"serviceConfig": {
"url": "/sap/opu/odata/.."
}
},
"routing": {
"config": {
"viewType": "XML",
"viewPath": "com.test.ui.view",
"clearTarget": false
},
"routes": [{
name: "route1",
view: "Desktop",
pattern: ":all*:",
targetControl: "rootapp",
targetAggregation: "pages"
}]
}
},
/**
* First method of the component to be called. It initializes the odata and the i18n models, calls the super constructor
* and initializes the router.
* #memberOf com.test.ui.Component
*/
init: function() {
// Fetch the rootpath of the component
var rootPath = jQuery.sap.getModulePath("com.test.ui");
//Create the i18n model with the properties file and set for the component with the name 'i18n'
var i18nModel = new sap.ui.model.resource.ResourceModel({
bundleUrl: rootPath + "/i18n/messageBundle.properties"
});
this.setModel(i18nModel, "i18n");
//Fetch the odata service url and create an odata model and set it for the component with the name 'odata'
var sServiceUrl = this.getMetadata().getConfig().serviceConfig.url;
var oModel = new sap.ui.model.odata.ODataModel(
sServiceUrl);
this.setModel(oModel, "odata");
var sServiceUrl1 = "/sap/opu/odata/...";
var oModel = new sap.ui.model.odata.ODataModel(
sServiceUrl1);
this.setModel(oModel, "odata1");
//call the super-constructor
sap.ui.core.UIComponent.prototype.init.apply(this,
arguments);
// Initialize route matched handler and router
this.oRouteMatchedHandler = new sap.m.routing.RouteMatchedHandler(
this.getRouter());
this.getRouter().initialize();
},
createContent: function() {
return sap.ui.view({
viewName: "com.test.ui.view.View1",
type: "XML",
viewData: {
component: this
}
});
}
});
});
Any help will be appreciated.
Project Structure

TypeError Controller.extend is not a function

When running my project, I am getting:
Error: failed to load 'stock/controller/plant.controller.js' from ./controller/plant.controller.js: TypeError: Controller.extend is not a function
Please, let me know how to fix it.
plant.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"jquery.sap.global",
"stock/Formatter",
"sap/ui/core/routing/History",
"sap/ui/model/json/JSONModel"
], function (jQuery, Formatter, Controller, History, JSONModel) {
"use strict";
var TableController = Controller.extend("stock.controller.plant", {
onInit: function () {
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
getRouter : function () {
return sap.ui.core.UIComponent.getRouterFor(this);
},
onNavBack: function (oEvent) {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getRouter().navTo("input", {}, true /*no history*/);
}
}
});
return TableController;
});
Component.js
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel"
], function(UIComponent, JSONModel, XMLView) {
"use strict";
var Component = UIComponent.extend("stock.Component", {
metadata: {
manifest: "json",
getTable: function () {
return this._rootView.getContent()[0];
}
},
publicMethods: [
"getTable"
],
dependencies: {
libs: [
"sap.m",
"sap.ui.layout"
]
},
rootView: "stock.view.input",
config: {
sample: {
files: [
"view.input.view.xml",
"controller.main.controller.js",
"Formatter.js"
],
description : "In this example assisted input is provided with table-like suggestions where several columns can display more details."
}
},
init : function () {
UIComponent.prototype.init.apply(this, arguments);
this.getRouter().initialize();
}
});
Component.prototype.createContent = function () {
this._rootView = sap.ui.xmlview({ viewName : "stock.view.plant" });
return this._rootView;
};
return Component;
});
You overlooked the sequence of the files declaration. In your example you use a "stock/Formatter" file as a "Controller", which is obviously wrong. Below is a correct sequence:
sap.ui.define([
'sap/ui/core/mvc/Controller',
'jquery.sap.global',
'stock/Formatter',
'sap/ui/core/routing/History',
'sap/ui/model/json/JSONModel'
], function (Controller, jQuery, Formatter, History,JSONModel) {
});

How to navigate to another XML page when the user click on message popup button

View1.Controller.js
onClickRUSSIA: function() {
var dialog = new Dialog({
title: 'Default Message',`enter code here`
type: 'Message',
content: new Text({
text: 'Country : RUSSIA \n Contenent : ASIA \n language:RUSSIAN.'
}),
beginButton: new Button({
text: 'OK',
press: function() {
dialog.close();
}
}),
endButton: new Button({
text: 'More Info',
press: function() {
//this.getRouter().navTo("mohan");
var router = sap.ui.core.UIComponent.getRouterFor();
router.navTo("View2");
}
}),
afterClose: function() {
dialog.destroy();
}
});
dialog.open();
},
Component.js
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"Test1/model/models"
], function(UIComponent, Device, models) {
"use strict";
return UIComponent.extend("Test1.Component", {
metadata: {
//rootView: "test1.webapp.view.App",
manifest: "json",
routing: {
config: {
viewType: "XML",
viewPath: "test1.webapp.view",
controlId: "rootControl",
controlAggregation: "pages",
//routerClass: "Test1.controller",
transition: "slide"
},
routes: [
{
pattern: "",
name: "default",
view: "view1"
}, {
pattern: "mohan",
name: "view2",
View: "view2"
}
]
// targets: {
// page1: {
// viewName: "View1",
// viewLevel: 0
// },
// page2: {
// viewName: "View2",
// viewLevel: 1
// }
// }
}
},
init: function() {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);
jQuery.sap.require("sap.m.routing.RouteMatchedHandler");
jQuery.sap.require("sap.ui.core.routing.HashChanger");
sap.ui.core.UIComponent.prototype.init.apply(this, arguments);
this._router = this.getRouter();
// set the device model
this.setModel(models.createDeviceModel(), "device");
//initlialize the router
this._routeHandler = new sap.m.routing.RouteMatchedHandler(this._router);
this._router.initialize();
}
});
});
You will have to get the router for your controller/view. As this is not your controller inside endButton.press(), you have to use a helper variable that.
You have to give Router.navTo() the name of the route to navigate to. So it has to be view2 instead of View2.
var that = this;
var dialog = new Dialog({
...
endButton: new Button({
text: 'More Info',
press: function() {
var router = sap.ui.core.UIComponent.getRouterFor(that);
router.navTo("view2");
}
}),
...
this.getOwnerComponent().getTargets().display("page1");

binding is not working in javascript model

I created javascript view
sap.ui.jsview("view.taskListView", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* #memberOf view.taskListView
*/
getControllerName : function() {
return "view.taskListView";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* #memberOf view.taskListView
*/
createContent : function(oController) {
var oLabel = new sap.m.Label("l1",{ text :"Weekly Tasks", textAlign:"Center", width:"100%"});
// var oList = new sap.m.List({noDataText:"No data", items:"{/modelData}"});
var oList= new sap.m.List({ // define List Control
// mode: "MultiSelect", // multi selection mode
columns : [
new sap.m.Column({ // first column
}),
new sap.m.Column({ // second column
})
],
items : [
new sap.m.ColumnListItem({ // first row
type : "Navigation",
//selected : true, // first item is selected (from ListItemBase)
cells : [
new sap.ui.core.Icon({
src : "{/iconTaskSource}",
size : "1.5em"
}),
new sap.m.Text({ // second cell related to second column definition
text : "{/taskName}"
})
]
}),
new sap.m.ColumnListItem({ // second row
type : "Navigation",
cells : [
new sap.ui.core.Icon({
src : "{/iconTaskSource}",
size : "1.5em"
}),
new sap.m.Text({ // second cell related to second column definition
text : "{/taskName}"
})
]
})
]
});
return new sap.m.Page({
title: "Title",
content: [
oLabel , oList
/*
new sap.m.Button({
text:"Go to Page2",
tap: function(){
//app.to("abc.SecondPage");
alert("Hello");
}
})
*/
]
});
}
});
and controller
sap.ui.controller("view.weeklyTasks", {
onInit: function() {
var aData2 = { modelData : [
{iconTaskSource:"icon1", taskName: "task1"},
{iconTaskSource:"icon2", taskName: "task2"}
]};
var oModel = new sap.ui.model.json.JSONModel(aData2);
this.getView().setModel(oModel2);
}
});
The binding is not working
Did I miss something ?
Try running this code snippet.
sap.ui.jsview("view.taskListView", {
getControllerName: function() {
return "view.taskListView";
},
createContent: function(oController) {
var oLabel = new sap.m.Label("l1", {
text: "Weekly Tasks",
textAlign: "Center",
width: "100%"
});
var oList = new sap.m.List({ // define List Control
columns: [
new sap.m.Column({ // first column
})
]
});
var oTemplate = new sap.m.ColumnListItem({
type: "Navigation",
cells: [
new sap.m.Text({
text: "{taskName}"
})
]
});
oList.bindItems('/modelData', oTemplate);
return new sap.m.Page({
title: "Title",
content: [
oLabel, oList
]
});
}
});
sap.ui.controller("view.taskListView", {
onInit: function() {
var aData2 = {
modelData: [
{
iconTaskSource: "icon1",
taskName: "task1"
}, {
iconTaskSource: "icon2",
taskName: "task2"
}
]
};
var oModel = new sap.ui.model.json.JSONModel(aData2);
this.getView().setModel(oModel);
}
});
var oApp = new sap.m.App();
var myView = sap.ui.view({
type: sap.ui.core.mvc.ViewType.JS,
viewName: "view.taskListView"
});
oApp.addPage(myView);
oApp.placeAt('content');
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<title>test</title>
<script id='sap-ui-bootstrap' type='text/javascript' src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-theme='sap_bluecrystal' data-sap-ui-libs='sap.m'></script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>
Check this for the fixed version of your code http://jsbin.com/kequme/1/edit
You neeed to include data-sap-ui-xx-bindingSyntax="complex" in index.html file.
Look:
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-xx-bindingSyntax="complex" data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal">
</script>