This is about how to get a model in the onInit method of a controller in SAPUI5.
The model can’t be acquired by this.getView().getModel() in the onInit method—the return value is undefined.
But there is another way: learn here how to get the model in a controller’s onInit method.
Let’s get started!
Why Does this.getView().getModel() Return Undefined in a Controller’s onInit Method?
The usual way to get a model in a controller in SAPUI5 doesn’t work in the onInit method:
// in your controller
...
onInit: function() {
var oModel = this.getView().getModel("yourModel");
}
...
this.getView().getModel() returns undefined in an controller’s onInit method.
Here’s why:
this.getView().getModel() in a controller’s onInit method returns undefined because this.getView().getParent() returns null in a controller’s onInit method.
And this.getView().getParent() returns null because the controller view’s parent was not known yet in the onInit method. But the not-yet-known parent holds the model for the view and therefore the the model for the controller. The view and its parent get connected after the onInit method is executed.
The model is passed from the view’s parent to the view, but in a controller’s onInit method, the parent has not yet passed the model to the view.
For clarification, this is how an SAPUI5 application executes:
- Start of the application (index.html)
- Load UI5 resources
- Index’s bootstrap loads component (component.js)
- Component loads descriptor (manifest.json)
- Component creates models defined in the descriptor // models are instantiated
- Execute component’s init function
- Component’s init function executes parent UIComponent’s init function
- Parent UIComponent’s init function creates manifest’s router
- Parent UIComponent’s init function creates manifest’s root view (view1.view.xml)
- Root view creates root control
- Component’s init function initializes router
- Router create other necessary views
- Each view loads corresponding controller (view1.controller.js)
- Each controller executes init method // each controller’s init method is executed
- Router places views in root control // each view knows its parent
- Models are available in the views // each view and its controller are able to access the models
- evaluate view’s bindings
- retrieve model data
To summarize:
The component instantiates the models defined in the descriptor (manifest.json). The component then passes down the models within the application. However, a model cannot be passed down to a view until it’s indirectly connected to the component.
The connection happens when a view gets connected to its parent. But these connections happen after the execution of the onInit method of the controller (steps 14. and 15).
Hence, this.getView().getParent() returns null when the onInit method of a controller is called—the parent gets connected to the view after the execution of onInit. So this.getView().getModel() returns undefined in the onInit method of a controller—the parent of a view holds the model.
Why You Don’t Need to Care About that the onInit Method in a Controller Returns Undefined for this.getView().getModel()
You don’t have to worry about the onInit method in a controller returning undefined for this.getView().getModel(). That is right and her’s why:
There’s a workaround to get a model in the controller’s onInit method. You can get the model directly from the application’s component with this.getOwnerComponent().getModel():
// in your controller
...
onInit: function() {
var oModel = this.getOwnerComponent().getModel("yourModel");
}
...
Because this.getOwnerComponent() returns the owner component of the controll’s component. And the application’s component is mighty.
this.getOwnerComponent() pulls the model directly from the component. Not indirectly from a view’s parent that was not connected to the view at the time of the controller’s onInit method execution (once more).
Check the SAPUI5 application life cycle above for clarification if needed.
Pew.