1

I am calling the GetEntity OData read method from the SAP UI5 view controller and passing a key value in the request URL. I am getting the proper response from the back-end when I hardcode the key value.

However, when I try to pass the key value dynamically in a variable by appending it to the URL, it doesn't work. I get the following error

HTTP request failed 404

In below code, sGrant is the variable and it doesn't work. But if I replace the variable name with its value hard-coded in below code, for example, in the read method like this: "/GrantMasterSet('TY560003')", then it works:

var sGrant = this.byId("grantNbr").getValue();
var oMod = this.getOwnerComponent().getModel();
oMod.read("/GrantMasterSet('sGrant')", {
  success: function(oData) {
    var oJsonModel =  new JSONModel();
    oJsonModel.setData(oData);
    this.getView().setModel(oJsonModel);
  }.bind(this),
  error: function(oError) {
    MessageToast.show("Read Failed");
  }
});
Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
goku_ssj3
  • 35
  • 1
  • 6
  • 1
    Does this answer your question? [How to Create Entity Path Dynamically in UI5?](https://stackoverflow.com/questions/46954621/how-to-create-entity-path-dynamically-in-ui5) – Boghyon Hoffmann Jul 17 '21 at 13:14

3 Answers3

5

UI5 has a method to generate the right URI for you, no matter what is the data type of the key of your entity type.

The method is createKey of the sap.ui.model.odata.v2.ODataModel class. See its documentation

Inside your controller, use the following source code.

onInit: function () {
    var oRouter = this.getOwnerComponent().getRouter();
    oRouter.getRoute("routeName").attachPatternMatched( this.onPatternMatched , this );
},

onPatternMatched: function(oEvent){
    var oParameters = oEvent.getParameters();
    var oArguments = oParameters.arguments; // is not a function - without ()
    var sKey = oArguments.id; // route parameter passed when using navTo

    var oDataModel = this.getView().getModel(); // v2.ODataModel

    oDataModel.metadataLoaded().then(function() {

            var sPath = oDataModel.createKey("EntitySet", {  Key: sKey });
            this.getView().bindElement("/" + sPath);

        }.bind(this)
    );

}

Usually this is necessary in details pages, in order to apply element binding to a page. As the createKey method relies on the $metadata of your service, you must make sure that it is already loaded in your app. This can be achieved by using method metadataLoaded, provided in the snippet as well.

fabiopagoti
  • 1,467
  • 14
  • 31
-1

You should concatenate the variable to the rest of the string, like this:

oMod.read("/GrantMasterSet('" + sGrant + "')", {

Or, you can use a template literal, which comes down to the same thing (notice the backtics):

oMod.read(`/GrantMasterSet('${sGrant}')`, {
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    Although this is correct it has the following drawbacks: 1) Depending on your key type, the URI must follow a different format. For example, when the key is a GUID, the key if totally different. If it's an integer, you won't have single quotes. 2) Template literals are not supported in IE 11 . See https://caniuse.com/#feat=template-literals – fabiopagoti Mar 29 '19 at 16:03
-2

You should escape 'sGrant' so it can be evaluated.

It should be something like that :

var sGrant = this.byId("grantNbr").getValue();
var oMod = this.getOwnerComponent().getModel();

oMod.read("/GrantMasterSet("+sGrant+")", {
    success: function(oData) {
        var oJsonModel =  new sap.ui.model.json.JSONModel();  
        oJsonModel.setData(oData);
        this.getView().setModel(oJsonModel);
    }.bind(this),
    error: function(oError) {
        MessageToast.show("Read Failed");
    }
});