Skip to Content

Dynamically replace default OData Model

Hello SAP UI5 Experts,

I have a SAPUI5 Applicaiton that has a default OData Model defined in the manifest.json

"": {
	"dataSource": "mainService",
	"settings": {
		"metadataUrlParams": {
			"sap-documentation": "heading"
		},
		"defaultBindingMode": "TwoWay"
	}
}

now we want to use the same application against different OData Services that implement different authorizations. The interface of the service is always the same. For that I've implemented the following function in the Component.js of my App:

_setDefaultModelForUser: function () {
	var that = this;
	var _odata1 = "/group1/service.xsodata";
	var _odata2 = "/group2/service.xsodata";
	var serviceUrl = "";
	var oManifest = this.getManifestObject();
	var oCurrentUser = this.getModel("currentUser");
	oCurrentUser.attachRequestCompleted(function() {
		var username = oCurrentUser.getProperty("/name");
		
		switch(username) {
			case "P598692":
				serviceUrl = _odata1;
				break;
			case "S0001142741":
				serviceUrl = _odata2;
				break;
			default:
		}
		
		if(serviceUrl !== "") {
			oManifest._oManifest["sap.app"].dataSources.mainService.uri = serviceUrl;
			var oDefaultModel = that.getModel("");
			var defaultModelSettings = oManifest._oManifest["sap.ui5"].models[""].settings;
			oDefaultModel = new sap.ui.model.odata.v2.ODataModel(serviceUrl, defaultModelSettings);
			that.setModel(oDefaultModel, "");
		}
	});
}


I call this method at the beginning of the init function:

init: function() {
	this._setDefaultModelForGroup();

Unfortunately this has no effect of the default model. Only the metadata is loaded, but the default model isn't replaces.

Hope someone could jump in here with some help.

Best regards
Gregor

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

8 Answers

  • Aug 28, 2017 at 03:25 PM

    Or maybe you could define your different data sources in the manifest and set the data source in the component's init?

    "dataSources": {
         "service1": {
             "uri": "/group1/service.xsodata",
             "type": "OData",
             "settings": {
          "odataVersion": "2.0",
          "localUri" : "localService/metadata.xml"
           }
         },
         "service2": {
             "uri": "/group2/service.xsodata",
             "type": "OData",
             "settings": {
          "odataVersion": "2.0",
          "localUri" : "localService/metadata.xml"
           }
         }
      }
    
    var oManifestEntry = this.getMetadata().getManifestEntry("sap.ui5");
    oManifestEntry.models[""].dataSource = "service1";
    
    Add comment
    10|10000 characters needed characters exceeded

  • Aug 28, 2017 at 01:53 PM

    Why do you need to use the default model? Maybe it is easier to define two models and set the model you use on a different place?

    Add comment
    10|10000 characters needed characters exceeded

  • Aug 28, 2017 at 02:33 PM

    Just a thought - are you attaching the event handler early enough to be triggered (for the requestCompleted event)?

    Add comment
    10|10000 characters needed characters exceeded

  • Aug 29, 2017 at 06:57 AM

    I would extend the app and replace the OData service through configuration, just as we do with any Fiori app.

    Component.extend("blablabla.Component", {
    	metadata: {
    		version: "1.0",
    		config: {
    			"sap.ca.serviceConfigs": [{
    				"name": "",
    				"serviceUrl": "/Northwind/V2/Northwind/Northwind.svc/",
    				"isDefault": true,
    				"mockedDataSource": "./localService/metadata.xml"
    			}]
    		}
    	}
    });
    
    Add comment
    10|10000 characters needed characters exceeded

  • Aug 28, 2017 at 01:46 PM

    Cant you just use the application component extension and do something like this ?

        metadata: {
            config: {
                "sap.ca.serviceConfigs": [{
                    name: "SERVICE NAME DEFINED IN THE METADATA",
                    serviceUrl: "/sap/opu/odata/sap/NEW_SERVICE_URL/",
                    isDefault: true,
                    useBatch: true           
                }]
            }
        }
    Add comment
    10|10000 characters needed characters exceeded

    • Hi Giovanni,

      thank you for your tip regarding the extension. I've created now two extensions of our main app where I've then did a service replacement. Now just the Launchpad has to be configured to use the different apps according to the User's Group assignment.

      Best regards
      Gregor

  • Aug 28, 2017 at 02:03 PM

    how about moving those code to a later point?

    component--->app

    how about app controller?

    Add comment
    10|10000 characters needed characters exceeded

  • Aug 28, 2017 at 02:42 PM

    Hi Gregor,

    I think your changes on the manifest and the default OData model are too late. The component already initialized everything before your request has been completed.

    I suggest to try removing the OData model definition in the manifest.json, so it won't initialize a default model. Keep the "_setDefaultModelForUser" function as it is but remove the code that manipulates the manifest.json.

    I would still use the destinations to define your different services.

    Hope it helps.

    Best regards,

    Wouter

    Add comment
    10|10000 characters needed characters exceeded

  • Aug 28, 2017 at 03:14 PM

    Gregor,

    I've had success with the same approach suggested by Wouter.

    In my case, I've one model for online use and the other one for offline use and it's set at onInit event.

    Best regards,

    Douglas

    Add comment
    10|10000 characters needed characters exceeded