-3

I'm trying to set a model and retrieving it from OData after pressing a certain button.

The problem is when I call getModel right after setting the model, it returns undefined.

However, if I call getModel from another function (after model being stetted from other functions), it returns the desired output.

Code for reference:

onPressButton1: function(){
            var vEntityURL = "/CustomerSet(ID='000')";
            var sServiceUrl = "/Customers_SRV/";
            var oServiceModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true);
            var oJsonModel = new sap.ui.model.json.JSONModel();

            oServiceModel.read(vEntityURL, {
                success: function(oData) {
                    oJsonModel.setData(oData);
                }
            });

            this.getView().setModel(oJsonModel, "Customers");

            var oCustomer = this.getView().getModel("Customers");
            console.log(oCustomer.getProperty("/Name"));
}

The above returns undefined in the console.

However, it works if I press another button with the following function.

onPressButton2: function(){
                var oCustomer = this.getView().getModel("Customers");
                console.log(oCustomer.getProperty("/Name"));
    }
Abdulelah
  • 77
  • 3
  • 10
  • 1
    A bit off topic but how come you're still using the deprecated `sap.ui.model.odata.ODataModel`? Where did you get the code from? Which tutorial are you following? And why not the official documentation? – Boghyon Hoffmann Jul 21 '20 at 09:16
  • Right @BoghyonHoffmann, I missed that! – Cmdd Jul 21 '20 at 09:27
  • @BoghyonHoffmann Because for some reason `odata.v2` returns an error `The Data Services Request could not be understood due to malformed syntax` even though I defined it in my controller modules. – Abdulelah Jul 21 '20 at 10:12
  • @Abdulelah Please upgrade to `v2.ODataModel` and open a new question with the error message and, if possible, an [mcve](https://stackoverflow.com/help/minimal-reproducible-example). Using the deprecated ODataModel should be avoided since it relies heavily on sync XHRs causing poor UX. – Boghyon Hoffmann Jul 21 '20 at 14:20

1 Answers1

1

This is not a sapui5 problem, it is the common behaviour of asynchronous code: you can be sure to have your data only in the success callback of the read method.

Move the last three lines of code inside the success function and you're done :-)

Cmdd
  • 867
  • 1
  • 10
  • 22
  • Yes that works but how would I be able to call functions starting with this key word like "this.fDoThis();" or even edit an object model outside of success? Thank you! – Abdulelah Jul 21 '20 at 09:23
  • Once your model is set, you can perform all kind of operation as you do in your onPressButton2 function, retrieving data from the model itself. I strongly recommend you to dive deeper in the MVC pattern and in the official documentation https://sapui5.hana.ondemand.com – Cmdd Jul 21 '20 at 09:32
  • I'll definitely check that as UI5 is new to me. I now understand that "success" function that sets the model will be called after my whole "onPressButton1" function is called. Could you please give me a hint on how to call success first? – Abdulelah Jul 21 '20 at 10:10
  • The success function is automatically triggered when the "success" event of the oServiceModel.read function is raised. In other words you make your read request then, when the data is ready, the success event is fired asynchronously and your custom function is called. So I can't understand what you mean when you say "call success first", sorry – Cmdd Jul 21 '20 at 10:47
  • What I meant is the model will not be set unless the whole function is triggered as you stated. Meaning if I click the button 1 time it will return undefined. if I click it a 2nd time it will give me that data. My goal is to do it on the first click. Thank you for your kind explanation. – Abdulelah Jul 21 '20 at 10:56
  • 1
    The only way you can achieve that is moving your logic inside the success function or wrapping your call inside a Promise. Take a look: https://www.nathanhand.co.uk/blog/post/better-odata-handling-in-ui5-using-promises-part-1 – Cmdd Jul 21 '20 at 12:31
  • `Promise.all([]).then` has done the job for me. Thank you, very useful resource! – Abdulelah Jul 22 '20 at 03:28