Closed s-v-o closed 1 year ago
Hello s-v-o,
am I getting this right that you are complaining that the onExit hook gets executed AFTER the objects have been destroyed? Is there a way that you can provide some code samples to get a better understanding what you are going to do and how those objects (i.E. the ODataModel) are being initialized?
I informed the responsible development team which will provide further information. In case of questions you can refer to the internal ID 2270138172.
Regards Sebastian (SAPUI5 Development Support)
Thank you for your reply.
For an executable example I need some time.
But essentially it is something like this:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/ObjectListItem",
"sap/m/ObjectAttribute"
], function(Controller, ObjectListItem, ObjectAttribute) {
"use strict";
return Controller.extend("sap.ui.demo.MockServer.controller.App", {
onExit: function(){
this.getView().getModel().callFunction("/MyFunctionImport", { method: "POST" })
}
});
});
Hi @s-v-o,
it's hard to say what actually happens here wrt. the ODataModel, but I'll outline the general the destruction lifecycle of a Component below:
destroy()
of the application Component instancedestroy()
of the sap.ui.core.UIComponent
base classdestroy()
of the sap.ui.core.Component
base classdestroy()
of the sap.ui.base.ManagedObject
base classexit()
hook on application instance is calledIn general the exit()
hook of a Component is intended for clean-up only and not for additional workload.
The intention behind this is partly because we can't catch any asynchronous behavior anymore after the Component is destroyed (at least not currently).
So in general the exit()
hook should only take care of destroying controls/fragments/... that are not managed by the framework. All the stuff you can see in the above list is framework managed, e.g. Models created via the Component, Views created via Routing and so on.
A controller's onExit hook is executed at the same time as the beforeExit
event of the View.
I think the reason why this doesn't work for you either is the following:
While the onExit
hook of the Controller still has access to the Model instance, the function import is asynchronous, but the whole destruction process is synchronous (and has to stay this way for compatibility reasons).
This means that while you might be able to trigger the function import asynchronously, the Model will be destroyed regardless when the Component Models are cleaned up (Number 5).
I presume this leads to the case that the Model is already destroyed when some internal ODataModel promise resolves and thus runs into the missing metadata issue.
So I think the issue is that you are using a framework managed Component Model created through manifest definition. A standalone model you create yourself will not be destroyed automatically, so you could use this in the exit hooks. However you must make sure to destroy it manually after your function import is resolved.
Best regards,
Thorsten
Thank you very much for your detailed explanation. It seems it is exactly what happens and your explanation help me to understand. I will try your suggested workaround and come back with an executable example.
On the other site it is a quite common task to talk back to the backend when leaving the app so I hope to see a better support therefore in the future.
I have added an example which illustrates the error further. But I think it confirms your analysis.
@Thodd Your suggested workaround is working and I can achieve what I want.
Thank you very much.
Here is an executable example: https://plnkr.co/edit/CLHQSabzTFroKTi6?preview
But it is not optimal, because I have to decide not to use the Component managed model or instantiate a new model (including a new request to metadata) in the onExit hook.
Also I could imagine, that a hook before the application Component instance is destroyed would be general useful.
But for me the workaround solves my problem at hand.
@Thodd With the given workaround I could solve my problem.
But in my opinion it is a bug, that I'm unable to use the component model in onExit.
If you disagree, you could close this issue.
Hi @s-v-o,
so I discussed this with a colleagues just now again and the bottom line is that the whole destroy lifecycle is just conceptually not equipped to deal with this. We consider this to more a conceptual weakness than a bug, since we currently don't have options to catch any asynchronous behavior. So from framework/component perspective there currently is no way to solve this compatibly.
However, I will forward this issue to the maintainers of the V2 ODataModel.
The model can theoretically be used from within the Controller#onExit
, but the (internal) callbacks themselves crash because of the already cleaned up metadata.
Maybe this can be made more robust, or maybe there could be a way to tell the model, that this function import is a "beacon-like" request...
BR, Thorsten
Hi @s-v-o,
so this is a rather old topic, but it recently came back up to my attention.
The stance on this is, that the exit() hooks are regarded as client-side only cleanup methods. They should only be used to tear down internal client-side only resources. The "exit" hook is not designed to cover use cases where any client-server communication can be reliably established. Since the Models itself are managed client-side resource (by the component) and have already been destroyed during the exit() handler, we do not regard this as a bug anymore. Any requesting function of the ODataModel cannot reliably used during exit().
The ODataModel v2 will also not provide another API to terminate serverside states (e.g. via a Beacon).
BR, Thorsten
Hi,
i have the same requirement as @s-v-o , "releasing a lock in the backend when the user leaves the app". I understand the flow in exit() of the component and that the model can not be used any more. But i would request a hook where OData calls are still possible as s-v-o already suggested. Or can you explain how it is handled in other UI5 applications, e.g. SAP UI5 application?
Best regards, lhendrik
Hi @lhendrik,
we are discussing internally to provide a possibility to send a Beacon request with the {{v4.ODataModel}}. As Beacon requests are POST requests this will mean to call an OData action in the OData service. As already written by @Thodd, there are no plans to provide a similar possibility with the {{v2.ODataModel}}. It is then required to use the Beacon API directly in the application.
Best regards Mathias.
OpenUI5 version:
Browser/version (+device/version): 1.71.49
Steps to reproduce the problem:
What is the expected result? OData Function Import should be called
What happens instead? Error message in JavaScript console
Any other information? (attach screenshot if possible)
I want to call an oData FunctionImport, when the user closes the app i.e. by navigate away through the launchpad shell buttons. But when I do so, I get an error because the oMetadata are not available anymore.
Why is this hook called after destroying half of the ODataModel?
It seems like a bug.
The only solution to get around this is to use some custom request (maybe XMLHttpRequest) and make the call without the ODataModel, but I don't think that this is desired behavior.
URL (minimal example if possible): https://plnkr.co/edit/LZ2WBEso3Nh5tTBb