JavaScript 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.

Answer:1

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.

Answer:2

I have implemented the following graph with the edges rendered with d3.svg.diagonal(). However, when I try substituting the diagonal with d3.svg.line(), it doesn't appear to pull the target and source ...

I have implemented the following graph with the edges rendered with d3.svg.diagonal(). However, when I try substituting the diagonal with d3.svg.line(), it doesn't appear to pull the target and source ...

How is it possible to detect with an eventListener when mousemove has finished? document.AddEventListener('mousemove', startInteractionTimer, false); function startInteractionTimer(){ ...

How is it possible to detect with an eventListener when mousemove has finished? document.AddEventListener('mousemove', startInteractionTimer, false); function startInteractionTimer(){ ...

I am a n00b in node, and find util.inherits() very useful, except for the fact that it seems to replace the entire prototype of the original object. For instance: var myClass = function(name){ ...

I am a n00b in node, and find util.inherits() very useful, except for the fact that it seems to replace the entire prototype of the original object. For instance: var myClass = function(name){ ...

I need to set the language_in option on the Closure compiler to prevent the IE8 parse error: ERROR - Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. ...

I need to set the language_in option on the Closure compiler to prevent the IE8 parse error: ERROR - Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. ...