Openui5: Which of `sap.ui.require` or `sap.ui.define` should I use when writing an UI5-controller?

Created on 17 Oct 2020  路  6Comments  路  Source: SAP/openui5

As far as I understand, in many cases sap.ui.require and sap.ui.define are interchangeable. However, there is a convention:

  • Use sap.ui.define for controllers and all other JavaScript modules to define a global namespace. With the namespace, the object can be addressed throughout the application.

  • Use sap.ui.require for asynchronously loading dependencies but without declaring a namespace, for example code that just needs to be executed, but does not need to be called from other code.

I read this statement several times, but I'm not sure I got it completely.
For instance, when I write an UI5-controller for the specific UI5-view, then what should I use? And when I write a BaseController.js, which the rest of the controllers will be based on, then should I chose sap.ui.define or sap.ui.require?

consulting

Most helpful comment

It's more than a convention, there are significant technical differences between the two APIs.

sap.ui.define _defines_ a module (nomen est omen). It is the outermost frame of a module, its entry point so to say.
The dependencies that are listed in the sap.ui.define call will be resolved before the factory function (the function given as argument to the sap.ui.define call) will be executed. And only after the function has executed, will others see your module and its return value (AKA "export"). Code outside your module has to wait for all the steps to complete before it can continue accessing your module.

For sap.ui.require, this second aspect of synchronisation is missing. It only resolves the listed dependencies and calls the callback function. But there's no export from a sap.ui.require call and no code besides the sap.ui.require call will wait for dependency resolution and execution of the factory function to happen. On the other side, sap.ui.require has a quality that sap.ui.define doesn't have. You can decide when to call it whereas sap.ui.define, as outer frame of a module will only be executed when a module is loaded and executed.

Well, if that explanation doesn't help to understand the difference, maybe a comparison with ES6 modules can help. sap.ui.define is more like the static import and export statements and sap.ui.require is more like the dynamic import() statement.

So when should you use what?
Whenever another piece of code shall be able to express a dependency to your code, you should place your code in a separate file and wrap it with sap.ui.define. That's true for controls, for renderers, for controllers, for JSViews, for components, for helpers, for model implementations etc. Most of the time, sap.ui.define is the only top-level code in a module.

In contrast to that, sap.ui.require usually is placed inside some method, often in an event handler. It will be used to load other code lazily that your module does not statically depend on (like with the sap.ui.define dependencies).

All 6 comments

It's more than a convention, there are significant technical differences between the two APIs.

sap.ui.define _defines_ a module (nomen est omen). It is the outermost frame of a module, its entry point so to say.
The dependencies that are listed in the sap.ui.define call will be resolved before the factory function (the function given as argument to the sap.ui.define call) will be executed. And only after the function has executed, will others see your module and its return value (AKA "export"). Code outside your module has to wait for all the steps to complete before it can continue accessing your module.

For sap.ui.require, this second aspect of synchronisation is missing. It only resolves the listed dependencies and calls the callback function. But there's no export from a sap.ui.require call and no code besides the sap.ui.require call will wait for dependency resolution and execution of the factory function to happen. On the other side, sap.ui.require has a quality that sap.ui.define doesn't have. You can decide when to call it whereas sap.ui.define, as outer frame of a module will only be executed when a module is loaded and executed.

Well, if that explanation doesn't help to understand the difference, maybe a comparison with ES6 modules can help. sap.ui.define is more like the static import and export statements and sap.ui.require is more like the dynamic import() statement.

So when should you use what?
Whenever another piece of code shall be able to express a dependency to your code, you should place your code in a separate file and wrap it with sap.ui.define. That's true for controls, for renderers, for controllers, for JSViews, for components, for helpers, for model implementations etc. Most of the time, sap.ui.define is the only top-level code in a module.

In contrast to that, sap.ui.require usually is placed inside some method, often in an event handler. It will be used to load other code lazily that your module does not statically depend on (like with the sap.ui.define dependencies).

Thanks a lot for the clarification, especially for a clear and brief parallel with the ES6 modules.

To conclude, do I understand it correctly, that basically the view controllers' code should start with sap.ui.define, while sap.ui.require should be used if in the middle of controller's code I want to import some functionality, located in another UI5 component?

Yes, exactly.

As your question seems to be answered, I'll close this issue now.

Thanks! Please, consider elaborating the official documentation, since there it's more represented as a matter of convention and taste, rather than a matter of architecture.

I've added this issue as feedback to the page that you linked initially.

Was this page helpful?
0 / 5 - 0 ratings