cancel
Showing results for 
Search instead for 
Did you mean: 

Return Web service data with a property

jens_we
Explorer
0 Kudos

Hi experts,

I am calling a web service and trying to return the result within a property. Unfortunantely the property is alway "" (empty) and I dont know why...

Here is the code, enriched with michaels hack

Component.js:

sap.designstudio.sdk.Component.subclass("com.sap.a.webservicecomp.WebService", function() {

  var that = this;

  var _websrvurl;

  var _user = "user";

  var _pw = "pw";

  var _execute;

  var _allnews = [];

  var _news = "";

  var _url;

  this.init = function() {

  };

  this.beforeUpdate = function () {

  };

  // Implement this function to execute JavaScript code after all properties of the custom extension component have been updated.

  this.afterUpdate = function() {

  // Verbindet WebService URL mit Paramtern

  _url = _websrvurl + _param;

  // Test

  if(_news == "" && _execute != "" ) {

  this.news(x.setExecute(_execute)); // work!

  alert("Test:" + this.news()); // work too!

  //that.firePropertiesChanged(["news"]); // has no effect

  }

};

   // Hack to call inside methods from Component

  var x = {

  someMethod : function(value) {

  alert("I am 'someMethod'.  You passed me value: " + value);

  // Call web service

  $.ajax({

  async: false,

  crossDomain: true,

  url: _url,

  headers: {

  'Authorization': "Basic " + btoa(_user + ":" + _pw)

  }

  }).done(function(dataArray) {

  _allnews = dataArray;

  });

  // Return one specific news

  return _.find(_allnews, function(y) {

         return y.identifier == value;

     }).news;

  },

  setExecute : function(s){

  var cmd;

  if(s) cmd = s.split("~");

  if(cmd!==undefined && cmd.length > 1){

  var methodNameParam = cmd[0].split("|");

  var methodName = methodNameParam[0];

  var methodParam;

  if(methodNameParam.length>1) methodParam = methodNameParam[1];  // noch ermöglichen das mehrere Parameter übergeben werden können

  if(this[methodName]) {

  return this[methodName](methodParam);

  } else {

  alert("You passed me a bad method (" + methodName + ")");

  }

  }

  },

  getExecute : function() {

  return String(Math.random());

  }

  };

  // Getter/Setter

  this.websrvurl = function(value) {

  if (value === undefined) {

  return _websrvurl;

  } else {

  _websrvurl = value;

  return this;

  }

  };

   this.execute = function(value) {

  if (value === undefined) {

  return _execute;

  } else {

  _execute = value;

  return this;

  }

  };

  this.news = function(value) {

  if (value === undefined) {

  return "Fixwert";

  } else {

  _news = value;

  return this;

  }

  };

});

Component.ztl

class com.sap.a.webservicecomp.WebService extends Component {

   /* Returns a specific News by Identifier */

  String getNews(String someId) {*

  this.execute = "someMethod|" + someId + "~" + Math.random();

  return this.news;  // return always "" (empty)

  *}

}

Contribution.xml

<?xml version="1.0" encoding="UTF-8"?>

<sdkExtension

  xmlns="http://www.sap.com/bi/zen/sdk"

  id="com.sap.a.webservicecomp"

  title="Design Studio SDK Extension WebService"

  version="14.0"

  vendor="xxx">

  <component

  id="WebService"

  title="Webservice Data Source"

  tooltip="Call SAP Webservice RESTful"

  icon="res/icon.png"

  handlerType="div"

  propertySheetPath="res/additional_properties_sheet/additional_properties_sheet.html">

  <jsInclude>res/js/underscore-min.js</jsInclude>

  <jsInclude>res/js/component.js</jsInclude>

  <property

  id="websrvurl"

  title="URL"

  type="Url"

  group="Webservice"/>

  <property id="news" title="Neues" type="String" group="Webservice" visible="true"/>

  <property type="String" title="Execute" id="execute" visible="false"/>

  </component>

</sdkExtension>

Now it is the problem, that the red marked code in the contribution.ztl doest return the result value from the web service.

Actually I am out of ideas to solve that issue. If I change the ztl from return this.news to return "test" it will run correctly and the string returned.

The fixed return value "Fixwert" is also never returned by the method "getNews("id")"...

I have following questions:

Q: How can i push this.news() value to the ZTL?

Q: It is possible to debug the contribution.ztl? I find nothing to do it?

I hope for your help

Thanks in advance,

jens

Accepted Solutions (1)

Accepted Solutions (1)

jens_we
Explorer
0 Kudos

To test the component i am using a "button" and a "textfield" in my design studio.

The onClick event implements the following snippet:

TEXT_1.setText(WEBSERVICE_1.getNews("id3"));

I have to push this "button" twice to get the news into the "textfield".

Hopefully anyone have an idea....

ps: i am using DS 1.4

reiner_hille-doering
Active Contributor
0 Kudos

I don't know the SAPUI5 Webservice control nor do I fully understand you code. But it seems to me that you want to do something synchronously which can't be easily done synchronously. For your Bial script

TEXT_1.setText(WEBSERVICE_1.getNews("id3"));


to work, the following steps would be required:

  1. From Bial script processor (running e.g. on BI platform the value "id2" should sent to the browser.
  2. The Bial script processor would need to wait until step ... ,
  3. The browser would receive "id3" by some property setter.
  4. Synchronously (in the setter) the web service request would be sent to the web server.
  5. The browser would wait for the webserver to respond.
  6. If the result is back, the interrupted browser function now has the result.
  7. The result would be now sent to BIP (Design studio runtime).
  8. The Bial script continues execution with the web service result.

Perhaps you can imagine that such a process does not make a lot of sense, as all the roundtrips - especially in step 5 could take arbitrary long time.

In Web programming usually works differently. Even in pure Browser Javascript you usually don't wait for a web service response. Instead you specify an (anonymous) callback function that is called as soon as the data is available.

I would split you Bial script into 2 parts. One scrip sends the "id3" to you web service.

Once the result is there, you Web Service component triggers an event. In the handler of the even you do the rest of your script.

Reiner.

jens_we
Explorer
0 Kudos

Thanks Reiner!

That hint helps a lot.

Former Member
0 Kudos

Hi Jens,

I am currently writing my masterthesis and have the same challenge: To call a Webservice and return data via Design Studio SDK Component.

Can you give me a hint how the solution looked like?

Thanks a lot

Frederic

Answers (1)

Answers (1)

jens_we
Explorer
0 Kudos

I have been making some proceedings, but its not the solution!

I changed this code in the Component.js

if(_news == "" && _execute != "" ) {

  this.news(x.setExecute(_execute)); // work!

  alert("Test:" + this.news()); // work too!

  //that.firePropertiesChanged(["news"]); // has no effect

  }

to

if(_execute != "" ) {

  this.news(x.setExecute(_execute)); // work!

  alert("Test:" + this.news()); // work too!

  that.firePropertiesChanged(["news"]); // works, but another roundtrip is needed!!

  }

Could someone help me to avoid these roundtrip? Or show me how to implement a "manual" roundtrip as workaround?