Search code examples
sapui5amd

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


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:

my SAPUI5 project folder


Solution

  • 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.