Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - SOAP Service Integration With AngularJS Model

I am a seasoned Flex Developer that is learning AngularJS. This is so confusing!!!

Anyway, I am trying to make a service call to my backend (on the same domain) server via a SOAP WSDL Request, and populate the data with an AngularJS model object. I was trying Ajax but was having some issues with getting the actual data back. I think there is something wrong with the way I created the SOAP tag. I was getting a successful response back, but no data.

After not being able to figure out the Ajax method, I came across soapclient.js and found it to be extremely easy, with less code than Ajax. soapclient.js does most of the work for you, similar to the Ajax method, which makes much less code. Additionally, using soapclient.js I am able to make the SOAP call and also get data back the XML formatted response.

http://javascriptsoapclient.codeplex.com

My issue is that I am trying to use AngularJS to dump the XML response into an AnularJS model object. I am not sure how to setup the AngularJS project for what I am doing, but I would really like to know the best method in order to keep what I am working on decoupled. I have been searching Google like crazy, but most examples seem overly complicated for a beginner.

Here is what I have:

<html>
<head>
    <script language="JavaScript" type="text/javascript" src="jquery-1.10.1.js"></script>
    <script language="JavaScript" type="text/javascript" src="soapclient.js"></script>

    <script type="text/javascript">
        function getData() {
            var url2 = "https://myService";
            var pl = new SOAPClientParameters();

            pl.add("arg0", false);

            SOAPClient.invoke(url2, "methodToCall", pl, true, getDataCallback);
        }

        function getDataCallback(r, soapResponse) {
            alert(r.contents.payeeMailName);
        }
    </script>
</head>

<body>
<form>
    <input type="button" value="Click Here to Call Web Service" onClick="getData()" style="width: 192px">
</form>
<div id="result">Result?</div>
</body>
</html>

Now, the SOAP service returns the data like this:

 <return>
    <contents>
       <eftAcctType>S</eftAcctType>
       <id>
          <djNumber>201-16-39063</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>124 Agate Drive</payeeAddrLine1>
    </contents>
    <contents>
       <eftAcctType/>
       <id>
          <djNumber>201-16-39201</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>c/o Kevin Martinez, Attorney at Law</payeeAddrLine1>
    </contents>
    <contents>
       <eftAcctType>C</eftAcctType>
       <id>
          <djNumber>201-16-38561</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>1360 South Highway 191</payeeAddrLine1>
    </contents>
    <status>0</status>
 </return>

What is the "proper" way in AngularJS to make the service call, assuming the way I did it is ok, if not let me know the best way, and then in the result, how do I loop through the data in the XML response and parse it into an Angular model object? I eventually want to use this data in a DataGrid.

Any help will be much appreciated.

like image 680
anad2312 Avatar asked Jul 05 '13 13:07

anad2312


2 Answers

Two years late, but I have built a Angular module specifically for working with SOAP web services that is on GitHub.

https://github.com/andrewmcgivery/angular-soap

Here is a blog post on how to use it: http://mcgivery.com/soap-web-services-angular-ionic/

Long story short, it allows you to do something like this:

angular.module('myApp', ['angularSoap'])

.factory("testService", ['$soap',function($soap){
    var base_url = "http://www.cooldomain.com/SoapTest/webservicedemo.asmx";

    return {
        HelloWorld: function(){
            return $soap.post(base_url,"HelloWorld");
        }
    }
}])

.controller('MainCtrl', function($scope, testService) {

  testService.HelloWorld().then(function(response){
    $scope.response = response;
  });

})
like image 103
Andrew McGivery Avatar answered Sep 26 '22 02:09

Andrew McGivery


I guess the best way would be to implement it as a $http interceptor. I did it in our project and it worked great because the angular $http calls stay the same.

This is a link to the provider I created for our project : http://jsfiddle.net/gqp9m/
I did some copy-paste from the soapclient library and moved it into a provider. I also changed a bit of the syntax so the code will pass jsHint. Most of the modified function are commented with documentation notes. It also requires jQuery (for the $.parseXML function - you can refactor it to remove dependency in jQuery).

The biggest difference is that my code does not load the wsdl on first request, but rather needs you to cache it before making any call, like so :

myModule.service(['myModule.soap-interceptor', function(soap){
    $http.get('http://www.myveryfakedomain.com/CRMAPIWS74?wsdl', 
    { isJSON: true }).then(function(result){
        soap.setWSDL('http:/www.myveryfakedomain.com/CRMAPIWS74', result.data);
    });
}]);

soap is the injected soap-interceptor instance. You call the wsdl and then call soap.setWSDL passing it the base url and the resolved wsdl. Also note the isJSON argument passed to the $http call. This is there because by default my code treats every call as a SOAP request. That's what interceptors do. isJSON:true will allow you to use $http as god intended ;)

After calling setWSDL just call $http like you always do:

$http.get('http:/www.myveryfakedomain.com/CRMAPIWS74/action').then(function(result){
    // do something...
});

Please remember that this code was written for our project and it's not a supported open source project or something. It may need of some level of maintenance or refactoring before you can use it, but it's a good start.

like image 43
Yair Tavor Avatar answered Sep 23 '22 02:09

Yair Tavor