SAP / ui5-typescript

Tooling to enable TypeScript support in SAPUI5/OpenUI5 projects
https://sap.github.io/ui5-typescript
Apache License 2.0
201 stars 28 forks source link

Error creating Singleton instance of sap.ushell.Container in SAPUI5 1.120.12 with TypeScript #465

Open Kasde96 opened 1 month ago

Kasde96 commented 1 month ago

Hello Experts,

I am encountering an issue with SAPUI5 version 1.120.12 when trying to create a Singleton instance of sap.ushell.Container to get a Navigation Service for navigating to another SAPUI5 application using a semantic object and action.

Problem

The intended method call, as per the API documentation, should be:

sap.ushell.Container.getServiceAsync("Navigation")

However, the linter reports an error, and even the API documentation's recommended approach does not work in TypeScript.

Code Snippet:

sap.ushell.Container.getServiceAsync("Navigation").then(function (navigation) {
    navigation.toExternal({
        target: {
            semanticObject: "SemanticObject",
            action: "action"
        }
    });
});

Linter Error

image

Additional Information

The issue might be related to an incorrect type definition file, as the method call provided in the API documentation also fails in TypeScript.

How should this method be correctly invoked in TypeScript to avoid the linting error? Could the type definition file for this version be incorrect?

Thank you for your assistance.

Best regards,

Dominik Kastenmeier

codeworrior commented 1 month ago

What types do you use? @sapui5/types or one of the older artifacts (@sapui5/ts-types or @sapui5/ts-types-esm)?

@sapui5/types intentionally only exposes modules, no globals (as they are deprecated and will disappear in UI5 2.0). So the right way to refer to the container is to require it, either as a dependency in the sap.ui.define call of your module or via sap.ui.require("sap/ushell/Container") (a probing require call, the module must have been loaded already, e.g. by the containing FLP).

[Edit by akudev: corrected old package names]

akudev commented 1 month ago

Might this be a duplicate of the old and still open issue https://github.com/SAP/ui5-typescript/issues/347 ?

Kasde96 commented 1 month ago

@codeworrior I am using the new types "sapui5/types". My expectation would be that I can import the "ushell.container" and then use it as a singleton/static class. That's what I did. I just adapted the coding to the API documentation therefore "sap.ushell.container".

Here is my coding:

import Event from "sap/ui/base/Event";
import Controller from "sap/ui/core/mvc/Controller";
import Container from "sap/ushell/Container";
import Navigation from "sap/ushell/services/Navigation";

export default class Actions {
       /**
     * custom action calling navigate to another app
     * @param {object} parameters
     */
    public static actionCustomNavigation(parameters: {
        event: Event;
        controller: Controller;
        standardActions: {
            [key: string]: (obj: { event: Event; controller: Controller }) => {};
        };
    }): void {
        (Container.getServiceAsync("Navigation") as Promise<Navigation>).then(
            (navigation) => {
                navigation.navigate({
                    target: {
                        semanticObject: "object",
                        action: "action",
                    },
                });
            }
        );
    }
}
Kasde96 commented 1 month ago

@akudev The "sap.ushell.container" is still there and working correctly at runtime, so i do not think it is related to the open issue #347. However, the problem is with the linter, which incorrectly flag it as an error.

Is there already an internal solution for this, as the other issue has been pending for two years?

codeworrior commented 1 month ago

@akudev: thanks for fixing the old package names, I was too lazy to look them up. @Kasde96: the globals (as used in the API reference) can't and should not work in TypeScript (when using @sapui5/types), as explained above. If the module import also doesn't work, then @akudev is right and this is the same issue as in #347.

This problem has been fixed in SAPUI5 version 1.121 and later (hint to @akudev: internal change 6026907 in ushell).

I checked with the current types and the following works without linter errors:

import Container from "sap/ushell/Container";
const navService = await Container.getServiceAsync("Navigation");

@aaronbruchsap any chance to downport your fix to 1.120 as this is the LTS version?

codeworrior commented 1 month ago

If a downport is not possible, the following might be a workaround in 1.120 (I did not test it, just sketched the idea- and it needs to be removed in 1.121ff):

// in 1.120, the export of sap/ushell/Container is still a class
import ContainerClass from "sap/ushell/Container"; 

// Container is typed as an instance of the class, using the export of the module at runtime 
const Container:ContainerClass = (ContainerClass as unknown);

// from here on it's the same
const navService = await Container.getServiceAsync("Navigation");
Kasde96 commented 1 month ago

@codeworrior Thanks for the workaround, the linter no longer shows errors. The only thing i get now is this error in the vscode. image

But that doesn't mind.

codeworrior commented 1 month ago

Does

public static Container: ContainerClass = ContainerClass as unknown as ContainerClass

help?

Kasde96 commented 1 month ago

Works perfectly, thank you.