Skip to Content
Technical Articles
Author's profile photo Johannes Gerbershagen

Learn JavaScript as ABAP developer Part 4

  1. Variable declaration
  2. Function declaration
  3. Concurrency with Promises and async functions
  4. Encapsulation with modules
  5. Scripting in UI5 applications

Encapsulation

Modules encapsulate functions and variables like a ABAP function group. They can be categorized in CommonJS modules and AMD modules. CommonJS modules are primary used by node.js application, whereas AMD modules are used by UI5. The API of these categories is a bit different.

CommonJS modules

CommonJS modules can be used for node.js applications or in most modern browsers.

Writing modules

A CommonJS module is written in one file. Every module has a object module.exports. Every property attached to this object can be used later. Functions or variables, which are not attached as property to this object, are just visible inside the module.
The following module exports the functions setBirthday and getBirthday, whereas the function normalizeBirthday is just visible inside the module.


let birthday;

function normalizeBirthday() {
        birthday.setHours(0);
        birthday.setMinutes(0);
        birthday.setSeconds(0);
}

module.exports.setBirthday = date => {
        birthday = new Date(date);
        normalizeBirthday();
}

module.exports.getBirthday = () => {
        return birthday;
}

Like variables in ABAP function groups variables inside of a module are cached throughout the execution process. Once the birthday is set in the function setBirthday, the function getBirthday returns this day in every invocation. When the process terminates, the cache is cleared.

Using modules

Modules can be imported with the require function. The require function returns the module.exports-object. Assuming the above module is declared inside a file birthday.js, it can be imported from another module in the same folder like this:


const birthday = require('./birthday');

birthday.setBirthday('2002-05-08');

The import statement can be used instead. This statement allows the import of a property subset or the import of the whole module.
To import a subset (just the function setBirthday):


import { setBirthday } from './birthday'.

To import the whole module:


import birthday from './birthday';

The prefix “./” refers to the location of the module-file. “./” means the current directory. If the module is located inside another folder, we add the relative posix-path. In node.js modules can come from other packages (like react or lodash) or can be local modules. Locale modules get always a path prefix, whereas modules from other packages don’t get any path prefix. Modules from other packages are always searched in the folder node_modules.

UI5 modules

UI5 has a own module loader, which uses the API of AMD modules.

Writing modules

Modules are defined with the sap.ui.define function. If no module name is specified, the first argument of this function is an array with dependencies (other modules). The second argument is the so called factory function, which contains the logic of this module. The dependencies must be supplied in the correct order to this function. The following module uses the dependency sap/ui/model/odata/v2/ODataModel to define an ODATA model object.


sap.ui.define(["sap/ui/model/odata/v2/ODataModel"], function(ODataModel){
  "use strict";
   return new ODataModel("/sap/opu/odata/sap/PP_MRP_COCKPIT_SRV");
});

It’s possible to add a unique module-name as first argument to the sap.ui.define function, but it’s not recommended.

sap.ui.define("Quickstart/App/model", ["sap/ui/model/odata/v2/ODataModel"], function(ODataModel){
  "use strict";
   return new ODataModel("/sap/opu/odata/sap/PP_MRP_COCKPIT_SRV");
});

The dependencies and the factory function are then the second and the third argument.

Using modules

Like CommonJS modules UI5 modules are referred with a relative or a global resource path. The relative resource path is according to the current directory. Global modules are loaded from SAP’s registry. UI5 provides the function sap.ui.require to directly access UI5 modules:


sap.ui.require([
	"./model"
], function (ODataModel) {
	"use strict";
        console.log(ODataModel);
});

It’s possible to include a module as a dependency of another module. A UI5 controller can make use of the above model-module:


sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"./model"
], function (Controller, ODataModel) {
	"use strict";
	return Controller.extend("Quickstart.App", {

		onInit : function () {
		    this.getView().setModel(ODataModel);
		},

		onChange: function (oEvent) {
			var bState = oEvent.getParameter("state");
			this.byId("ready").setVisible(bState);
		}

	});
});

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michael Lichtinger
      Michael Lichtinger

      Thanks for this great blog series.