Skip to Content
0

Dynamically replace default OData Model

Aug 28, 2017 at 01:38 PM

409

avatar image

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

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

8 Answers

Dominique Pierre Aug 28, 2017 at 03:25 PM
1

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";
Share
10 |10000 characters needed characters left characters exceeded
Mark Teichmann Aug 28, 2017 at 01:53 PM
0

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?

Share
10 |10000 characters needed characters left characters exceeded
DJ Adams
Aug 28, 2017 at 02:33 PM
0

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

Share
10 |10000 characters needed characters left characters exceeded
Mauricio Lauffer Aug 29, 2017 at 06:57 AM
0

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"
			}]
		}
	}
});
Share
10 |10000 characters needed characters left characters exceeded
Giovanni Degani Aug 28, 2017 at 01:46 PM
0

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           
            }]
        }
    }
Show 2 Share
10 |10000 characters needed characters left characters exceeded

he probably has many services....

0

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

1
Jun Wu Aug 28, 2017 at 02:03 PM
0

how about moving those code to a later point?

component--->app

how about app controller?

Share
10 |10000 characters needed characters left characters exceeded
Wouter Lemaire Aug 28, 2017 at 02:42 PM
0

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

Show 2 Share
10 |10000 characters needed characters left characters exceeded

what wouter said. don't define the model in the manifest but create it manually after receiving the user-type.

even better would be a polymorph service proxy... but...

0

Yep, that's also what I suggested in my answer earlier too ...

0
Douglas Cezar Kuchler Aug 28, 2017 at 03:14 PM
0

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

Share
10 |10000 characters needed characters left characters exceeded