goku_ssj3
goku_ssj3

Reputation: 35

How to pass a key field as variable instead of hard-coded key value to OData operation?

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");
  }
});

Upvotes: 1

Views: 6507

Answers (3)

fabiopagoti
fabiopagoti

Reputation: 1531

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.

Upvotes: 5

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");
    }
});

Upvotes: -2

trincot
trincot

Reputation: 349936

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}')`, {

Upvotes: -1

Related Questions