on 2022 Mar 04 3:33 PM
Hi experts,
we try to create a SAPUI5 app which should access a backend service on clicking a specific button.
The SAPUI5 app is created using the BTP managed app router. Basically it is consuming a OData service to display a worklist. For the OData service we have created a destination in BTP cockpit and everything works fine.
But now we try to implement another button which should call another backend service using jQuery AJAX. As this service requires authentication (and the URL differs depending on DEV, TEST and PROD) we created a destination for this as well. This destination looks as follows in BTP cockpit:
As our SAPUI5 is uses the managed app router we added an according route to the xs-app.json:
{<br> "routes": [<br> ...<br> {<br> "source": "^/srv/(.*)$",<br> "target": "/v1/$1",<br> "destination": "XXXXXXXX-srv",<br> "authenticationType": "xsuaa",<br> "csrfProtection": false<br> },<br> ...<br> ]<br>}
Within the SAPUI5 controller we have now a function defined which is triggered on a button press:
onButtonPress: function (oEvent) {<br> var oData = {};<br> jQuery.ajax({<br> type: "POST",<br> url: "/srv/createPdf",<br> dataType: "json",<br> body: oData,<br> headers: {<br> "Content-Type": "application/json",<br> },<br> success: function (oReturn, textStatus, jqXHR) {<br> //do something<br> },<br> error: function (error) {<br> console.error(error);<br> }<br> });<br>}
Unfortunately, when we try to execute this we see a 403 in the developer tools. Then we analyzed the URLs in the network tab within the browser developer tools a bit more. Here we found some interesting difference between the URL structure used for calling the OData service and for the AJAX request.
OData URL:
https://<btp-tenant>.launchpad.cfapps.<btp-region>.hana.ondemand.com/<managed-app-router-id>.<html5-...
AJAX Call URL:
https://<btp-tenant>.launchpad.cfapps.<btp-region>.hana.ondemand.com/<obackend-service-url>;
The AJAX Call misses the app router path including the html 5 ID. When we hard code this (by copying the path information from the OData call) we can access the backend service successfully. But we must not hard code this as the managed app router ID differs on DEV, TEST and PROD and the version is recalculated with every deploy.
So, the question is how can we access this information within the SAPUI5 controller to have the AJAX call working. Or what do we need to setup to access a destination for a jQuery AJAX call?
regards
René
Request clarification before answering.
You have to use a relative path srv/ or ./srv/. And if you run in Portal or Launchpad check out Calling Service using AJAX in Fiori Elements Extension doesn't work in Launchpad.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Gregor,
thanks for the link to the other question. With this information I rebuild the logic within the controller as below. Now everything is working fine.
onButtonPress: function (oEvent) {
var oData = {<some data>};
var sModelUrlPath = this.getOwnerComponent().getManifestEntry("/sap.app/dataSources/mainService/uri");
var sModelServiceUrl = this.getView().getModel().sServiceUrl;
var sAppRouterUrl = sModelServiceUrl.substr(0, sModelServiceUrl.length - sModelUrlPath.length);
jQuery.ajax({
type: "POST",
url: sAppRouterUrl + "/srv/createPdf",
dataType: "json",
body: oData,
headers: {
"Content-Type": "application/json",
},
success: function (oReturn, textStatus, jqXHR) {
//do something
},
error: function (error) {
console.error(error);
}
});
}
regards
René
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
My controller for view1 looks like this: ( and works perfect from BAS, but not from Cloud Foundry )
return Controller.extend("yr2.yr2.controller.View1", { onInit: function () {You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
As you try to call this in the onInit method of the controller, the model is not yet linked with the view. So, this.getView().getModel() will return "undefined" and you get an exception trying to read the sServiceUrl
In order to get the model you would need to change the code as follows:
this.getOwnerComponent().getModel().sServiceUrl
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
When do you try to connect to the model? If you do this in the onInit method, the model is probably not yet linked with the view. (See Assigning the Model to the UI)
You could try to get the URL as follows:
this.getOwnerComponent().getModel().sServiceUrl
I have the same problem, calling a "free weather service" API: Weather for Mandal
My "Freestyle Tile" works from BAS, but not from Cloud Foundry Launchpad.I added these 2 lines to my controller:
var sModelUrlPath = this.getOwnerComponent().getManifestEntry("/sap.app/dataSources/mainService/uri"); MessageBox.show(sModelUrlPath);
Giving this result:
/weatherapi/locationforecast/2.0/compact/ "Launchpad
/weatherapi/locationforecast/2.0/compact/ "Standalone
This line is not working:
var sModelServiceUrl = this.getView().getModel().sServiceUrl;
My destination looks like this:
Please suggest what is wrong ?
Best regards,
Rolf
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Rolf,
your data source "mainService" should be linked to a model in your manifest.json. What name has this model - is it empty (just "") or has it a name?
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService",
"preload": true,
"settings": {}
}
}
}
If the name of the model is not empty you would need to call the model like this:
var sModelServiceUrl = this.getView().getModel("<name>").sServiceUrl;
User | Count |
---|---|
89 | |
11 | |
9 | |
8 | |
7 | |
5 | |
4 | |
4 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.