cancel
Showing results for 
Search instead for 
Did you mean: 

Broken code completion in BAS?

gregorw
Active Contributor

Hello SAP BAS Team, Hi keren.rotenberg, Hi avitalmargalit,

I'm mentioning you Keren and Avital as you've published the blog posts SAP Business Application Studio – Product Walkthrough and The Value of SAP Business Application Studio where code completion is mentioned as one of the key features. But I currently have a quite different experience. Let me describe what is happening:

I start yo and choose the @sap/fiori generator and provide the following input:

? Application Type SAPUI5 freestyle
? Which floorplan do you want to use? SAP Fiori Worklist Application
? Data source Connect to an OData Service
? OData service URL https://sapes5.sapdevcenter.com/sap/opu/odata/sap/ZPDCDS_SRV
? Object collection SEPMRA_I_Product_E
? Object collection key Product
? Object ID Product
? Object number Price
? Object unit of measure Currency
? Module name worklist
? Application title App Title
? Application namespace 
? Description A Fiori application.
? Project folder path /home/user/projects/
? Minimum SAPUI5 version 1.102.8
? Add deployment configuration No
? Add FLP configuration No
? Configure advanced options Yes
? UI5 theme Morning Horizon
? Add Eslint configuration to the project. Yes
? Add javascript code assist libraries to your project. Yes
The first problem that now appears when I open webapp/controller/BaseController.js:There is no JSDoc provided.eslint(@sap/ui5-jsdocs/no-jsdoc)
OK, this can be solved by using the Quick Fix "fix all auto-fixable problems". I would hope that the generator would provide this out-of-the-box. But then the nex error occurs:Property 'core' does not exist on type 'typeof ui'.ts(2339)

When I do the same locally in VS Code, I can progress a bit more. The first error that occurs here is:

Property 'library' does not exist on type 'typeof m'.

Looking forward to see this issue solved.

Best Regards
Gregor

Accepted Solutions (1)

Accepted Solutions (1)

pmuessig
Advisor
Advisor

Hi Gregor,

andreas.kunz summarized the usage of the TypeScript d.ts files for JavaScript in the following README.md:
https://github.com/SAP-samples/ui5-cap-event-app/blob/js-with-typescript-support/README.md

Basically, it goes into much more detail like I described it above - explains how to declare the types of the imports, how to cast types, defining new types, ... But the JS code completion also has limitations, especially with the exposure of own UI5 classes and modules. If it is mainly about the consumption of the OpenUI5/SAPUI5 modules and classes, this can be fine.

I'll also follow-up with the colleagues providing the templates with the JS support. I think we need to adopt here and also explain the limitations...

Best regards,

Peter

gregorw
Active Contributor
0 Kudos

Hi Peter,

thank you for pointing me to this example. That's quite extensive and gives also a good background. I forward it to the developers and let them try on one of their projects.

Best Regards
Gregor

Answers (4)

Answers (4)

pmuessig
Advisor
Advisor

gregor.wolf

Looking into the types which provide code-assist for JavaScript they always struggle with being complete. We focussed on the TypeScript support using ES modules and classes rather the classic Globals usage. But this would require to use either TypeScript or at least transpilation. I need to check with the initial POC types provided so far- but I can't promise anything right now. The classic types with Globals (for the pure classic JS case) always were in a beta/experimental state... 😞

pmuessig
Advisor
Advisor
0 Kudos

Hi gregor.wolf

sorry, I missed to verify it yesterday. It is an issue with the newer generation of the types. Some modules like the sap.ui.model.* namespace are not exposed for in the @sapui5/ts-types. With an older version 1.71.15 you can check and see that it works. I'll check this with my colleagues...

Thanks for pointing this out...

Best regards,

Peter

gregorw
Active Contributor
0 Kudos

Hi Peter,

I've downgraded now to:

    "@sapui5/ts-types": "1.71.15",
But the error that I see in VS Code is still the same:
Property 'library' does not exist on type 'typeof m'.ts(2339)

In BAS it improved a bit and is now the same as in VS Code.

Best Regards
Gregor

gregorw
Active Contributor
0 Kudos

Hi Peter,

I've filed now the SAP Incident: 787334 / 2022. There I've described a very obvious issue. In Web IDE I get code completion for sap.m.Popover and even a link to the documentation:

The Web IDE Code Compleation features where also shown in Videos linked in this blog post: Code Assist in SAP Web IDE (video). But in BAS this control isn't even appearing:

Hope that also the BAS Team joins this discussion. Our developers moving from Web IDE expect more after BAS being GA for over 2.5 years now.

Best Regards
Gregor

CC: nirm.kol, raz.korn

pmuessig
Advisor
Advisor

Hi Gregor,

I understand your point. First some background: the WebIDE implemented a custom code completion support which is independent from the types based solution which is used in BAS. The reason for this is that the generic solution didn't exist at the time when this feature had been developed. This is also the reason why the WebIDE and the BAS code completion are technically two independent features.

The JavaScript types (@sapui5/ts-types) needed for BAS for the SAPUI5 code completion have never been officially released. They are still in the beta/experimental state (see also the description in the link above pointing to the README.md on npmjs.com). The usage of Globals is no longer recommended and the @sapui5/ts-types are relying on this. We furthermore recommend the explicit import of the dependencies with sap.ui.define or sap.ui.require (to finally get a better insight into the used dependencies and make the dependency import something explicit). We have been pushing the TypeScript types @sapui5/ts-types-esm so far which are based on the ES modules and there is no Global usage needed. I made a quick check with the esm types using the "@param {import ...}" syntax - but this isn't working yet - the constructor is not detected properly but the type could be resolved:

sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/core/UIComponent",
  "sap/ui/core/routing/History",
  "sap/m/Popover"
], 
/**
 * BaseController
 * @param {import("sap/ui/core/mvc/Controller").default} Controller
 * @param {import("sap/ui/core/UIComponent").default} UIComponent
 * @param {import("sap/ui/core/routing/History").default} History
 * @param {import("sap/m/Popover").default} Popover
 * @returns {BaseController} BaseController
 */
function (Controller, UIComponent, History, Popover) {
  "use strict";

  return Controller.extend("com.myorg.js.myapp.controller.BaseController", {
    getOwnerComponent: function() {
      (new Popover())
      return Controller.prototype.getOwnerComponent.call(this);
    },

As mentioned, the types for JavaScript were always in beta state and experimental and we didn't ensure a proper usage. The Fiori tools colleagues added the types to their project generation experimentally. As the JavaScript types have never been perfect and may also never been perfect we are more pushing for TypeScript because this is different and we can provide a proper type support.

Anyways, I need to take your point to an internal discussion. We didn't foresee an investment into the code completion for Globals. But maybe the hybrid approach I sketched above might be a proper way forward. This would unify the best of both worlds. This would not allow the usage of Globals but we could make the API usable. The only downside is, that the JSDoc is needed to map the types to the imports in sap.ui.define and sap.ui.require. This is a must as the types can't be derived from the code like in the WebIDE without the development of a SAPUI5 specific extension to the JavaScript editor. Instead of developing something proprietary, it would be better to rely on standards (like the integration into the language server).

Enough for now. We need to follow-up here.

Have a great weekend and best regards,

Peter

pmuessig
Advisor
Advisor

gregorw - a small update, since I got it running with the @openui5/ts-types-esm or @sapui5/ts-types-esm in the following way using JSDoc annotations:

/* eslint-disable no-new */
/* eslint-disable valid-jsdoc */
sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/core/UIComponent",
  "sap/ui/core/routing/History",
  "sap/m/Popover"
], 
/**
 * BaseController
 * @param {typeof import("sap/ui/core/mvc/Controller").default} Controller
 * @param {typeof import("sap/ui/core/UIComponent").default} UIComponent
 * @param {typeof import("sap/ui/core/routing/History").default} History
 * @param {typeof import("sap/m/Popover").default} Popover
 * @returns {any} BaseController
 */
function (Controller, UIComponent, History, Popover) {
  "use strict";

  return Controller.extend("com.myorg.js.myapp.controller.BaseController", {
    getOwnerComponent: function() {
      (new Popover().addContent(new Controller()));
      return Controller.prototype.getOwnerComponent.call(this);
    },
    getRouter: function() {
      return UIComponent.getRouterFor(this);
    },
    getResourceBundle: function() {
      /** @type {import("sap/ui/model/resource/ResourceModel").default} */
      const oModel = this.getOwnerComponent().getModel("i18n");
      return oModel.getResourceBundle();
    },

The parameters have to be typed with the following @param annotation:

/**
 * @param {typeof import("sap/m/Popover").default} Popover
 */
function (Popover) { ... }
And constants or variables can be typed with the following JSDoc annotation:
      /** @type {import("sap/ui/model/resource/ResourceModel").default} */
      const oModel = this.getOwnerComponent().getModel("i18n");
I'll check further with the teams whether this might be a proper way forward... At least it uses the ESM types we are continuously improving due to the TypeScript support. They also come with the benefit to not support the Globals (except of the mandatory stuff, like sap.ui.define/require, ...). So, this might be indeed a proper way forward. For completeness, I used the following tsconfig.json:
{
  "compilerOptions": {
    "module": "none",
    "noEmit": true,
    "checkJs": true,
    "allowJs": true,
    "types": [
      "@openui5/ts-types-esm"
    ]
  }
}
pmuessig
Advisor
Advisor
0 Kudos

Thanks gregor.wolf

the dependencies are ok. Did npm install run successfully and the dependencies are available in node_modules?

Thanks and best regards,

Peter

gregorw
Active Contributor
0 Kudos

npm install worked withouth issues:

➜  worklist ls -la node_modules/@sapui5 
total 0
drwxr-xr-x    3 gwolf  staff     96  7 Oct 16:58 .
drwxr-xr-x  340 gwolf  staff  10880  7 Oct 16:58 ..
drwxr-xr-x    6 gwolf  staff    192  7 Oct 16:58 ts-types
pmuessig
Advisor
Advisor
0 Kudos

Hi gregor.wolf ,

can you share your package.json with us to see which types have been added to the project? @sapui5/ts-types or @sapui5/ts-types-esm - the first one are the correct ones.

Best regards,

Peter

gregorw
Active Contributor
0 Kudos

Hi Peter,

this is the dependencies section:

  "dependencies": {},
  "devDependencies": {
    "@ui5/cli": "^2.14.1",
    "@sap/ux-ui5-tooling": "1",
    "eslint": "7.32.0",
    "@sap/eslint-plugin-ui5-jsdocs": "2.0.5",
    "@sapui5/ts-types": "1.102.x",
    "eslint-plugin-fiori-custom": "2.2.1",
    "@babel/eslint-parser": "7.14.7",
    "@sap-ux/ui5-middleware-fe-mockserver": "2"
  },

CU
Gregor