Show TOC

JavaScript Code IssuesLocate this document in the navigation structure

This section lists some of the most important issues that should be avoided when writing JavaScript code in SAPUI5.

Don't use private and protected methods or properties of SAPUI5

Don't use or override "private" and "protected" functions. Private functions are typically (but not always) prefixed with "_". Protected functions are indicated by a yellow diamond in front of the function name within the API Reference documentation.

Always double check in the API Reference documentation. If SAPUI5 changes the implementation in a future release, your code will break if you fail to follow this guideline.

Table 1: Examples
Bad Examples Good Example
var sText = oControl.mProperties["text"]; var sText = oControl.getText();
oSelectDialog._oList.setGrowing(false);  
var sPart = oEvent.oSource.oBindingContexts.description.sPath.split('/')[3];  

See also: Compatibility Rules.

Don't use deprecated APIs

Entities marked as “deprecated” in the API Reference documentation (this includes properties, methods, events, and their parameters as well as entire controls and other APIs) are no longer intended to be used. They will not get feature updates in the future. Alternatives, if available, are described in the API Reference documentation.

One prominent example is the old jQuery.sap.device API that has been replaced with sap.ui.Device.

Don't override or add control methods

If you override methods like onBeforeRendering, onAfterRendering, or getters and setters, the original methods will no longer be called. You have to make sure that you call them in your method explicitly. Even if they are not implemented right now, they could be added in the future. This applies to control inheritance in particular.

Instead, you should consider using delegates.

Table 2: Examples
Bad Examples Good Example
oControl.onAfterRendering = function() {
       // do something
};
oControl.addEventDelegate({
    onAfterRendering:function() {
        // do something
    }
});
oControl.prototype.setText = function(){ ... };  

See also sap.ui.core.Element - addEventDelegate in the Demo Kit.

Don't manipulate the DOM structure within controls

Manipulating the DOM structure of controls rendered by SAPUI5 can result in undesired behavior and only has a temporary effect. Changes will be overridden after the next rerendering or the DOM might change in a future version of SAPUI5, which can break your code. In addition, your DOM changes could break the code of the SAPUI5 control if it relies on a certain structure.

If you need to manipulate the DOM of an SAPUI5 control, attach a delegate to the afterRendering hook of the control, safeguard your code against DOM changes, but still be prepared to have to rework your code at any time when the DOM structure (which is in no way guaranteed to remain stable!) changes. The adaptation should be covered by your automated tests.

Even onAfterRendering may not be called when a control handles certain property changes without complete rerendering.

Table 3: Examples
Bad Examples Good Example
oControl.$().find(".sapMLabel")[0].innerHTML = "reallybad";
oControl.addEventDelegate({
	"onAfterRendering": function() {
		var $label = oControl.$().find(".sapMLabel");
		if (/* sanity check whether the change still makes sense */) { 
		      // TODO: re-test after UI5 updates, create automated test
			$label.text("Better");
		}
	}
});
oControl.$().find(".sapMLabel").remove();  
Don't attach DOM event handlers

Use attachBrowserEvent() if you need to listen to any DOM event on SAPUI5 controls. An even better approach is to use addEventDelegate() for the most important event types instead, as it avoids additional event registrations and listens to the regular SAPUI5 event dispatching.

If you are creating event handlers in custom controls, you can use listen to DOM events directly, but make sure that the listeners are properly deregistered in onBeforeRendering() and in exit(), and registered in onAfterRendering().

Good example for arbitrary events:

oControl.attachBrowserEvent("mousemove", function() {
	// do something
});

Good example for wide but limited selection of browser events:

oControl.addEventDelegate({
        onmouseover:function() {
            // do something
        }
    });

See also sap.ui.core.Control - attachBrowserEvent and sap.ui.core.Element - addEventDelegate in the Demo Kit.

Don't create global IDs (when running with other views or apps)

When you create JSViews or applications that will be running together with views or applications from other sources (that are not owned by you), or JSViews that will be instantiated several times in parallel, you must not create stable IDs for your controls, fragments, or views in SAPUI5. Doing so might result in duplicate ID errors that will break your app. Especially when running together with other apps, there could be name clashes or other errors.

Use the createId() function of a view or controller instead. This is done automatically in XMLViews and JSONViews. The createId() function adds the View ID as a prefix, thus recursively ensuring uniqueness of the ID (for example: __page0--__dialog0).

Table 4: Examples
Bad Example (Inside a JSView) Good Example (Inside a JSView)
createContent: function(oController) {
	var btn = new sap.m.Button("myBtn", {text: "Hello"});
	return btn;
}
createContent: function(oController) {
	var btn = new sap.m.Button(this.createId("myBtn"), {text: "Hello"});
	return btn;
}

See also sap.ui.core.mvc.View - createId in the Demo Kit.

Don't forget about control lifecycle management

SAPUI5 controls are kept alive until they are destroyed, so lifecycle management of controls is important since multiple apps can be opened and closed in the same user session. Controls that are not destroyed cause memory leaks and may slow down the browser after prolonged use.

Also clean up internal structures in controllers, views and your custom controls.

See also sap.ui.core.Element - destroy (for applications) and sap.ui.core.Element - exit (for custom control implementation) in the Demo Kit.

Don't hard code or concatenate strings that need to be translatable

Hard coding UI strings will exclude them from translation. In addition, concatenating translatable strings in applications might lead to errors in internationalization: the texts in question might have a different translation order in other languages and will then be syntactically wrong.

Table 5: Examples
Bad Example Good Example

Using separate texts like " you selected " and " items " in the translation file to construct sentences like: " you selected " + 10 + "items ". This would lead to a wrong word order in languages where the verb needs to be at the end of the sentence, for example.

Using a complete sentence including a placeholder in the translation file: " you selected {0} items ". This allows translators to change the word order and the position of the inserted placeholder value.

Don't forget about proper "this" handling

For developers new to JavaScript, it is often confusing to understand how the "this" keyword behaves. In event handlers in particular, but also for other callback functions, the "this"-pointer must be used correctly, so make sure you check what it actually refers to. Without proper usage of the execution context, unexpected results can occur (this-pointer might be the global window object or a different control).

Don't use console.log()

There is an API available for logging errors and warnings in the developer console of your browser, but some browsers might even crash while you are using it (because "console" is only defined while the console is actually open). Use jQuery.sap.log.* instead, which offers different severities as well as additional filter strings. jQuery.sap.log.setLevel() then defines the minimum severity to be logged.

Note that most errors and warnings in the developer console thrown by the SAPUI5 framework are potential bugs in your application and must be analyzed thoroughly!

Table 6: Examples
Bad Example Good Example
console.log("some message"); jQuery.sap.log.info("some message");

See also Namespace jQuery.sap.log in the Demo Kit.

Don't use timeouts

Executing logic with timeouts is often a workaround for faulty behavior and does not fix the root cause. The timing that works for you may not work under different circumstances (other geographical locations with greater network latency, or other devices that have slower processors) or when the code is changed. Use callbacks or events instead, if available.

Table 7: Examples
Bad Example Good Example
jQuery.ajax("someData.json");
setTimeout(fnProcessResults, 300);
jQuery.ajax("someData.json").done(fnProcessResults);
Don't build apps without reasonable automated tests

This should not come as surprise, but it is very difficult to refactor or modify apps that do not have any (or have bad) automated test cases. There are substantial risks when QUnit and OPA tests are missing in applications.