Reading REST Service with SAPUI5

DI MI picture DI MI · Nov 20, 2013 · Viewed 27.5k times · Source

I am trying to access a REST Service with SAPUI5. I am sending a GET Request with the help of jQuery and expect a JSON respond, but all i get is an empty JSON Object. However the REST service tested with a RESTClient gives me the correct respond.

Here is the code i am using sofar:

View

sap.ui.jsview("sapui5_test.SAPUI5_Test", { 

    getControllerName : function() {
        return "sapui5_test.SAPUI5_Test";
    },

    createContent : function(oController) {

    var text = new sap.ui.commons.TextField( {  
        width : "100%"  
    }); 

// arrange controls on the page with a matrix layout  
    var ml = new sap.ui.commons.layout.MatrixLayout( {  
        columns : 2,  
        layoutFixed : true,  
        width : "500px"  
    }); 

    ml.addRow(new sap.ui.commons.layout.MatrixLayoutRow( {  
        cells : [  
            new sap.ui.commons.layout.MatrixLayoutCell( {  
                content : [ text ]  
            })]  
    }));

    var model = oController.initTodoModel();

    text.setValue(model.getJSON());
    return [ ml ];
    }   



});

Controller

sap.ui.controller("sapui5_test.SAPUI5_Test", {

initTodoModel : function() {  
            var oModel = new sap.ui.model.json.JSONModel();
            var aData = jQuery.ajax({
                type : "GET",
                contentType : "application/json",
                url : "http://sapm04.ibsolution.local:50000/demo.sap.com~d337_resttest_web/rest/todo/init/",
                dataType : "json",
                success : function(data,textStatus, jqXHR) {
                    oModel.setData({modelData : data}); 
                    alert("success to post");
                }

            });

            return oModel;  
        }
}

});

index.html

<!DOCTYPE HTML>
<html>
<head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

      <script src="resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
              data-sap-ui-libs="sap.ui.commons,sap.ui.table,sap.ui.ux3"
            data-sap-ui-theme="sap_goldreflection">
    </script>
    <!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->

    <script>
            sap.ui.localResources("sapui5_test");
            var view = sap.ui.view({id:"idSAPUI5_Test1", viewName:"sapui5_test.SAPUI5_Test", type:sap.ui.core.mvc.ViewType.JS});
            view.placeAt("content");
    </script>

</head>
<body class="sapUiBody" role="application">
    <div id="content"></div>
</body>

As already mentioned, when i run the same URL as in the jQuery in a RESTClient, i am getting a filled JSON Object as a result, however the result in the UI5 page is an empty JSON obejct {}.

I also tried the following solution:

var oModel = new sap.ui.model.json.JSONModel("http://sapm04.ibsolution.local:50000/demo.sap.com~d337_resttest_web/rest/todo/init/");

but this didn't help.

Answer

Mohamed Ali JAMAOUI picture Mohamed Ali JAMAOUI · Nov 21, 2013

Well, the reason is obvious. the return statement in the controller finishes executing before the json object is filled with data. That's because the $.ajax call is asynchronous which means that JavaScript does the call to the backend server and doesn't wait till the answer is sent, rather JavaScript goes straight to the next instruction which is return oModel before having the oModel filled with data. If you make a synchronous request to the backend your problem will be resolved, you can do that this way:

 sap.ui.controller("sapui5_test.SAPUI5_Test", {

 initTodoModel : function() {  
        var oModel = new sap.ui.model.json.JSONModel();
        var aData = jQuery.ajax({
            type : "GET",
            contentType : "application/json",
            url : "http://sapm04.ibsolution.local:50000/demo.sap.com~d337_resttest_web/rest/todo/init/",
            dataType : "json",
            async: false, 
            success : function(data,textStatus, jqXHR) {
                oModel.setData({modelData : data}); 
                alert("success to post");
            }

        });

        return oModel;  
    }
  }

 });

However, using synchronous calls is not recommended because it will halt the application until the request is done.

Why you shouldn't use synchronous requests?

Just imagine halting your application till the call is finished. That might not be a great deal for few requests but if you have a large application that requires a lot of interaction with a backend data provider then this will be a major issue.

Design improvement suggestion:

If it's up to me, I would design the application so that I am able to register callback functions into the ajax request. So the application would follow a chain of responsibility like design pattern and when the data is ready, the module depending on it will be executed and it won't halt the other modules of the application.

In simple terms, do whatever you want to do with the data by calling a function within the success function and not outside the $.ajax call.