Fragment won't open due to the error "Cannot instantiate object: 'new' is missing!" - sapui5

Unfortunately, my fragment page won't open.
Trying to open a select dialogue (fragment with table) after a button press.
Here is the error:
formatter function sap.f.FlexibleColumnLayoutWithOneColumnStart.controller.Formatter not found!
Uncaught (in promise) Error: Cannot instantiate object: "new" is missing!
󠀠󠀠󠀠󠀠󠀠    at constructor (Object-dbg.js:39:11)
    at constructor (EventProvider-dbg.js:29:14)
    at constructor (ManagedObject-dbg.js:464:17)
    at constructor (Fragment-dbg.js:122:17)
    at f._configDialog (DetailDetail.controller.js?eval:120:4)
    at f.eval (DetailDetail.controller.js?eval:84:10)
I have a Formatter in my project folder. The property _pDialog seems to be empty, although my view clearly exists.
The error is in the method handleTableSelectDialogPress.
sap.ui.define([
"sap/ui/model/json/JSONModel",
"sap/ui/core/mvc/Controller",
"sap/ui/core/Fragment",
"sap/m/MessageToast",
"./Formatter",
"sap/ui/core/Fragment",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/ui/model/json/JSONModel",
"sap/ui/core/syncStyleClass",
], function(JSONModel, Controller, Fragment, MessageToast, FilterOperator, syncStyleClass) {
"use strict";
return Controller.extend("sap.f.FlexibleColumnLayoutWithOneColumnStart.controller.DetailDetail", {
// ...,
handleTableSelectDialogPress: function(oEvent) {
var oButton = oEvent.getSource(),
oView = this.getView();
if (!this._pDialog) {
this._pDialog = Fragment.load({
id: oView.getId(),
name: "sap.f.FlexibleColumnLayoutWithOneColumnStart.view.Dialog",
controller: this
}).then(function(oDialog) {
oView.addDependent(oDialog);
return oDialog;
});
}
this._pDialog.then(function(oDialog) {
this._configDialog(oButton, oDialog);
oDialog.open();
}.bind(this));
},
_configDialog: function(oButton, oDialog) {
// ...
syncStyleClass("sapUiSizeCompact", this.getView(), oDialog);
},
// ...
});
});
This is my view:
<mvc:View displayBlock="true" controllerName="sap.f.FlexibleColumnLayoutWithOneColumnStart.controller.DetailDetail" height="100%" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.f" xmlns:m="sap.m">
<DynamicPage toggleHeaderOnTitleClick="false">
<!-- ... -->
<content>
<m:Button
class="sapUiSmallMarginBottom"
text="Show Table Select Dialog"
press=".handleTableSelectDialogPress"
ariaHasPopup="Dialog" />
</content>
</DynamicPage>
</mvc:View>
This is my Fragment:
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
<TableSelectDialog id="myDialog"
title="Select Product"
search=".handleSearch"
confirm=".handleClose"
cancel=".handleClose"
items="{
path: '/ProductCollection',
sorter: {
path: 'Name',
descending: false
}
}">
<ColumnListItem vAlign="Middle">
<!-- ... -->
</ColumnListItem>
<columns>
<!-- ... -->
</columns>
</TableSelectDialog>
</core:FragmentDefinition>
This is my project folder:

There is a mismatch of the required dependencies in the array with the callback parameters of the controller factory function:
sap.ui.define([
"sap/ui/model/json/JSONModel",
"sap/ui/core/mvc/Controller",
"sap/ui/core/Fragment",
"sap/m/MessageToast",
"./Formatter", // <-- here you required Formatter
"sap/ui/core/Fragment", // <-- required Fragment (again)
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/ui/model/json/JSONModel", // <-- required JSONModel (again)
"sap/ui/core/syncStyleClass",
], /*factory*/function(JSONModel, Controller, Fragment, MessageToast, FilterOperator/*<-- Formatter */, syncStyleClass/*<-- Fragment */) {/* ... */});
Consequently, the parameter syncStyleClass is not the module sap/ui/core/syncStyleClass but sap/ui/core/Fragment! And calling Fragment() without new results in the error "new" is missing!.
The name of the function parameters is not relevant to the framework. Important is the correct order of those parameters according to the list of dependencies. From the API reference of sap.ui.define:
The module export of each dependency module will be provided as a parameter to a factory function, the order of the parameters will match the order of the modules in the dependencies array.
The same rule applies to sap.ui.require.

Related

Adding a SimplePlanningCalendar to a UI5 app fails with `getKey` error

When I add a SimplePlanningCalendar to my app, I got the following Error.
I added the calendar with a minimal configuration to my app.
<IconTabBar xmlns="sap.m"
id="idCategoryMenu"
selectedKey="Home"
headerMode="Inline"
stretchContentHeight="true"
applyContentPadding="false"
select=".onSelectCategory"
items="{
path: 'backend>/CategorySet',
parameters: {
expand: 'Reports'
},
sorter: {
path: 'Sort'
},
templateShareable: true
}">
<items>
<IconTabFilter id="myIconTabFilter" key="{backend>Uuid}" text="{backend>Name}">
<!-- ... -->
<SinglePlanningCalendar>
<appointments>
<unified:CalendarAppointment xmlns:unified="sap.ui.unified"
title="{title}"
startDate="{startDate}"
endDate="{endDate}"
/>
</appointments>
</SinglePlanningCalendar>
<!-- ... -->
</IconTabFilter>
</items>
</IconTabBar>
When I debug the app, I come to the following line inside the SinglePlanningCalendar.js where a key from the given vView parameter is requested, but the parameter only holds a string.
Anyone else had this problem before and knows why or how to solve this?
The problem is caused by the control implementation itself in the current version (1.71.21) I use for my development.
The fix in the commit 45696fe is available as of UI5 1.75.x.
Since I cannot change my version, I implemented the given solution in my package:
{ // Controller
onInit: function () {
// ...
this.calendarTemporaryFix(); // Not needed since UI5 1.75
},
calendarTemporaryFix: function () {
// SinglePlanningCalendar required from "sap/m/SinglePlanningCalendar"
const fnSetSelectedView = SinglePlanningCalendar.prototype.setSelectedView;
SinglePlanningCalendar.prototype.setSelectedView = function (vView) {
if (typeof vView === "string") {
vView = sap.ui.getCore().byId(vView);
}
return fnSetSelectedView.call(this, vView);
};
},
// ...
}

SAPUI5 SmartChart with CDSView Annotations is not Displayed

I am pretty new to the SAP environment and couldn't find a suitable solution to the following problem in the community forum or using the samples/templates/API docs or SAP books, thus I am asking this question.
My Problem: I created a CDS-View with Annotations (for a table and a chart) and linked it using my service to an own SAPUI5 application. While the SmartTable is created without any problems, the SmartChart is giving me the following error:
TypeError: can't convert undefined to object RoleFitter.js
I looked up the error and it seems like something is not correct in the annotations file. However, I couldn't find an error and since it is auto-generated from the CDS-View Annotations I am a little confused (the SmartTable is working and I can add/change UserText Annotations without any problem).
Furthermore, when I use the created CDSView wit a standard SAP template (e.g. in cards in an Overview Page Template) it works just fine.
For any solutions or hints I am super thankful since this is bothering me a lot and I don't understand why the SmartTable is working but the chart isn't.
Thanks in advance!
CDSView:
#AbapCatalog.sqlViewName: 'ZYSS20MSGITEST3'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #NOT_REQUIRED
#EndUserText.label: 'Test view 3'
#UI: {headerInfo: {
typeName:'Test3',
title:{
type: #STANDARD,
label: 'Suche'
}
}
}
#UI.chart: [{
qualifier: 'OccupiedSeats',
chartType: #COLUMN,
dimensions: [ 'FlightCode' ],
measures: [ 'MaximumCapacity', 'EconomyOccupiedSeats', 'BusinessOccupiedSeats', 'FirstOccupiedSeats' ]
}]
define view ZY_SS20_MSGI_TEST3
as select from sflight
{
#UI.lineItem: [ { position: 10 } ]
key concat(carrid, connid) as FlightCode,
#UI.lineItem: [ { position: 30 } ]
seatsmax as MaximumCapacity,
#UI.lineItem: [ { position: 40 } ]
seatsocc as EconomyOccupiedSeats,
#UI.lineItem: [ { position: 50 } ]
seatsocc_b as BusinessOccupiedSeats,
#UI.lineItem: [ { position: 60 } ]
seatsocc_f as FirstOccupiedSeats
}
Dashboard.controller.js:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("ZY_SS20_MSGI_TESTN.controller.Dashboard", {
onInit: function() {
this._oModel = new sap.ui.model.odata.ODataModel("/sap/opu/odata/sap/ZY_SS20_MSGPROGRESSSRV_SRV/", true);
this.getView().setModel(this._oModel);
}
});
Dashboard.view.xml:
<mvc:View controllerName="ZY_SS20_MSGI_TESTN.controller.Dashboard" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns:smartChart="sap.ui.comp.smartchart"
xmlns:data="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1" xmlns:smartFilterBar="sap.ui.comp.smartfilterbar" xmlns:smartTable="sap.ui.comp.smarttable"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<VBox fitContainer="true">
<smartFilterBar:SmartFilterBar
id="smartFilterBar" entitySet="ZY_SS20_MSGI_TEST3" />
<smartTable:SmartTable id="mySmartTable"
entitySet="ZY_SS20_MSGI_TEST3" smartFilterId="smartFilterBar"
tableType="Table" useExportToExcel="true"
useVariantManagement="false" useTablePersonalisation="false"
header="Throughput" showRowCount="true" enableAutoBinding="true"
initiallyVisibleFields="FlightCode,MaximumCapacity,EconomyOccupiedSeats,BusinessOccupiedSeats,FirstOccupiedSeats">
</smartTable:SmartTable>
<smartChart:SmartChart entitySet="ZY_SS20_MSGI_TEST3"
enableAutoBinding="true" id="mySmartChart" useVariantManagement="false"
useChartPersonalisation="false" header="Test"></smartChart:SmartChart>
</VBox>
</content>
</Page>
</pages>
</App>
</mvc:View>
The problem seems to be that you are providing a qualifier to the chart annotation but not specifying the same to the SmartChart control. Try adding this property to your SmartChart tag:
data:chartQualifier="OccupiedSeats"

sapui5 Not able to display data in detail page

I have a problem to display data in my detail page. I've tried almost everything but its dosnt work. On main page everything looks fine. Routing work (display proper ID on network address).
Details.controller.js :
return Controller.extend("sapProject.controller.Details", {
onInit: function () {
var oTable = this.getView().byId("details");
var oModel = new sap.ui.model.json.JSONModel();
oModel.loadData("model/Object.json");
oTable.setModel(oModel);
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("Details").attachMatched(this._onRouteMatched, this);
},
_onRouteMatched : function (oEvent) {
var oArgs, oView;
oArgs = oEvent.getParameter("arguments");
oView = this.getView();
oView.bindElement({
path : "/Objects(" + oArgs.employeeId + ")",
events : {
dataRequested: function () {
oView.setBusy(true);
},
dataReceived: function () {
oView.setBusy(false);
}
}
});
},
and this is my Details.view.xml:
<Page
id="details"
title="{i18n>EmployeeDetailsOf} {FirstName} {LastName}"
showNavButton="true"
navButtonPress="onBack"
class="sapUiResponsiveContentPadding">
<content>
<Panel
width="auto"
class="sapUiResponsiveMargin sapUiNoContentPadding">
<headerToolbar >
<Toolbar>
<Title text="{i18n>EmployeeIDColon} {EmployeeID}" level="H2"/>
<ToolbarSpacer />
</Toolbar>
</headerToolbar>
<content>
<f:SimpleForm>
<f:content>
<Label text="{i18n>FirstName}" />
<Text text="{FirstName}" />
<Label text="{i18n>LastName}" />
</f:content>
</f:SimpleForm>
</content>
</Panel>
</content>
</Page>
I think you are binding an empty model to your detail view because probably the loadData function is not completed when you set the model on the Table.
Try to load your json file in the manifest (best option) or differ the setModel on the _onRouteMatched function (although I don't see any table in your detail view).
EDIT:
You can also use this code after oModel.loadData("model/Object.json");
oModel.attachEventOnce("requestCompleted", function(oEvent) {
// Here your file is fully loaded
});
Firstly I recommend you to bind like this:
var sObjectPath = this.getModel().createKey("Objects", {
ID: oArgs.employeeId
});
this._bindView("/" + sObjectPath);
...
}
_bindView: function (sObjectPath) {
//Todo: Set busy indicator during view binding
this.getView().bindElement({
path: sObjectPath,
parameters: {
},
events: {
change: this._onBindingChange.bind(this),
dataRequested: function () {
}.bind(this),
dataReceived: function () {
}.bind(this)
}
});
},
Secondly check if oArgs.employeeId has a valid value and also if the model is loaded with data, easily set a brekapoint or write console.log(this.getView().getModel().oData).

SAP UI 5 XML-Templating / Preprocessing

I try to use the template:if for my XML View.
As an example i have this:
<mvc:View controllerName="Test_Start.controller.View"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mvc="sap.ui.core.mvc"
xmlns:temp="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<temp:if test="{= ${Data>Enable1} === 'X'}">
<Text text="Hallo"/>
</temp:if>
</content>
</Page>
</pages>
</App>
</mvc:View>
and my Component.js looks like this:
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"Test_Start/model/models",
"sap/ui/model/odata/v2/ODataModel",
"sap/ui/core/util/XMLPreprocessor"
], function(UIComponent, Device, models, ODataModel, XMLPreprocessor) {
"use strict";
return UIComponent.extend("Test_Start.Component", {
metadata: {
manifest: "json"
},
/**
* The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
* #public
* #override
*/
init: function() {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);
// set the device model
this.setModel(models.createDeviceModel(), "device");
},
onBeforeRendering: function(){
var oModel = new ODataModel("/sap/opu/odata/SAP/ZPFO_CKPT_ODATA_DYN_SRV/"),
oMetaModel = oModel.getMetaModel(),
sPath = "/DataSet";
oMetaModel.loaded().then(function() {
var oTemplateView = sap.ui.view({
preprocessors: {
xml: {
bindingContexts : {
meta : oMetaModel.getMetaContext(sPath)
},
models: {
meta: oMetaModel
}
}
},
type : sap.ui.core.mvc.ViewType.XML,
viewName: "Test_Start.view.View"
});
oTemplateView.setModel(oModel);
oTemplateView.bindElement(sPath);
});
}
});
});
Now, when I try to run my App, i get the following error:
XMLTemplateProcessor-dbg.js:53 Uncaught Error: failed to load
'http://schemas/sap/com/sapui5/extension/sap/ui/core/template/1/if.js'
from
../../resources/http://schemas/sap/com/sapui5/extension/sap/ui/core/template/1/if.js:
404 - Not Found
I did some research and found out, that i probably load the preprocessor at the wrong time, but I seem to can't find the right place to load it.
I use this SAPUI5 SDK example for my work.
Edit
I found a solution for my problem:
instead of an "onBeforeRendering" function, now i'm using a "createContent" function. Also i deleted the "init" completly.
In adition to that, I implemented an oViewContainer, like it is used in the sample.
Also controller name "Test_Start.Component" doesn't match the controllerName attribute in the view "Test_Start.controller.View".

Data binding issue with sap.m.SelectDialog

I'm using Sap.m.SelectDialog to display the value request(F4 help in abap).When i do it with JS view all is good,but when do it with XML view by creating the fragment, binding is not happening with the "items" aggregation.
please let me know what went wrong.
var mydata = { data : [
{
info: "SAP UI5",
name: "Sam",
},
{
info: "SAP UI5",
name: "Ram",
},
{
info: "SAP UI5",
name: "Prem",
}
]};
Js view logic:
var oDialog = new sap.m.SelectDialog({
title: "Select an item",
items: {
path:"/data",
template : new sap.m.StandardListItem({
title: "{name}"
})
}
})
oDialog.open();
}
XML fragment :
<SelectDialog xmlns="sap.m"
id ="id3"
title="Select a product">
<items id="ls3"
path="/data">
<StandardListItem title="{name}">
</StandardListItem>
</items>
.
Reslut of JS view
Result of Xml view
Try XML fragment this way:
<SelectDialog xmlns="sap.m"
id ="id3"
items="{/data}"
title="Select a product">
<items>
<StandardListItem title="{name}"/>
</items>
</SelectDialog>