SOAP Web Services in Angular and Ionic

SOAP Web Services in Angular and Ionic

posted in: Uncategorized | 80

In my post Ionic: Using Factories and Web Services for Dynamic Data, I covered the basics of consuming a RESTful web service from within an Ionic app using Angular’s $http module and a factory.

The question came up, however, of what about SOAP? Does Angular have support for SOAP web services? The answer is… not really. Fortunately, after some research and experimentation, I came up with angular-soap, an Angular module for consuming SOAP web services.

In this post, I’ll talk a bit about what it does and how to use it in an Ionic App.

JavaScript SOAP Client

First thing to know is that this module is a wrapper around another library called JavaScript SOAP Client. The library itself is a bit old (last updated 2006), however SOAP hasn’t really changed much since then, so it still works beautifully.

Some of the nice features include sending and receiving of objects. This means it will map objects you send it to SOAP parameters and will map a response of an object or objects to JavaScript equivalents.

Abstraction

The original syntax of the SOAP Client is as follows:

SOAPClient.invoke(url, action, params, asyc, callback);

params is a SOAPClientParameters object which is essentially just a dictionary of key value pairs. We add to it using the add method.

var soapParams = new SOAPClientParameters();
soapParams.add(key, value);

for our abstraction, we’ll have a similar syntax except that we’ll use promises and have the method accept a JavaScript object of key value pairs that we will map to a SOAPClientParameters object.

Here’s what our abstraction looks like:

angular.module('angularSoap', [])

.factory("$soap",['$q',function($q){
	return {
		post: function(url, action, params){
			var deferred = $q.defer();
			
			//Create SOAPClientParameters
			var soapParams = new SOAPClientParameters();
			for(var param in params){
				soapParams.add(param, params[param]);
			}
			
			//Create Callback
			var soapCallback = function(e){
				if(e.constructor.toString().indexOf("function Error()") != -1){
					deferred.reject("An error has occurred.");
				} else {
					deferred.resolve(e);
				}
			}
			
			SOAPClient.invoke(url, action, soapParams, true, soapCallback);

			return deferred.promise;
		}
	}
}]);

NOTE: Previously, this abstraction incorrectly exposed the method as get which was incorrect because the library actually sends your request via POST. It does however send the request for your WSDL over GET.

The module, angularSoap, contains one factory called $soap that contains one method, post. The post method returns a promise that if resolved contains the response or if rejected simply contains a generic error message.

As I mentioned above, you’ll see we look through the javascript object that is passed in and map it to a SOAPClientParameters object.

Our soapCallback, which is passed to the SOAPClient.invoke method, contains the reject and resolve logic.

Usage

Before using the factory, you must import the two scripts and its module:

<script src="soapclient.js"></script>
<script src="angular.soap.js"></script>
angular.module('myApp', ['angularSoap']);

Then, wherever you are going to consume it, make a reference to the $soap service for dependency injection:

.factory("testService", ['$soap',function($soap){
//use it here
}])

$soap‘s one method, post, accepts the following parameters:

Parameter Description Example
url The base URL of the service “http://www.cooldomain.com/SoapTest/webservicedemo.asmx”
action The action you want to call “HelloWorld”
params An object of parameters to pass to the service { name: “Andrew” }

The syntax of the method is as follows:

$soap.post(url,action,params);

As mentioned, similar to $http methods, $soap.post returns a promise that you can act upon.

$soap.post(url,action,params).then(function(response){
    //Do Stuff
});

Remember: Response will be a javascript object containing the response mapped to objects. When developing, do a console.log of response so you can see what you are working with.

Examples

Example 1: Hello World

Let’s start with a basic “Hello World” style call with no parameters.

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;
  });

})

In this basic example, we are creating a factory, testService, which has a single method: HelloWorld. This method makes a SOAP call with no parameters to our base_url with the action "HelloWorld". This method returns the promise that our $soap factory returns.

In our MainCtrl controller, we are calling the HelloWorld method and setting it’s response to a $scope variable.

Example 2: Invoke with Parameters

Let’s make another call, this time passing in a couple of parameters.

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

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

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

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

  testService.CreateUser($scope.firstName, $scope.lastName).then(function(response){
    $scope.response = response;
  });

})

Very similar to our first example except the difference here the method is called CreateUser and we are passing in firstName and lastName to our testService. You’ll notice on our $soap.post call we pass in our third parameter, a JavaScript object of parameters.

Example 3: Get Single Object

Next, let’s look at what it would look like to get a single object. For this example, we’ll call a GetUser method that accepts an id.

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

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

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

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

  testService.GetUser($scope.id).then(function(user){
    console.log(user.firstName);
    console.log(user.lastName);
  });

})

You’ll notice in our controller that the response back from $soap is an actual JavaScript object! This is the magic of the library is that it maps the SOAP response in the background.

Example 4: Get Many Objects

Another example, similar to example 3, however this time we’ll call a GetUsers function which will return an array of JavaScript objects:

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

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

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

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

  testService.GetUsers().then(function(users){
    for(i=0;i<users.length;i++){
        console.log(users[i].firstName);
        console.log(users[i].lastName);
    }
  });

})

Example: Ionic App

Let’s take a look at how we might use this in an Ionic App. Assume we are using the following factory:

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

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

We want to get a response from the GetUsers method and list all of our users out in the following view:

<ion-view title="About">
	<ion-content>
		<div ng-repeat="user in users">
			{{user.firstName}}
			{{user.lastName}}
		</div>
	</ion-content>
</ion-view>

All we have to do in our controller is call our factory and assign the response to the $scope.users variable:

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

	userService.GetUsers().then(function(users){
		$scope.users = users;
	});

})

… and that’s it! It’s that simple.

Conclusion

Calling a SOAP web service can be just as easy as calling a RESTful service, given the right abstraction. Hopefully this module and this blog post will help someone who may need it!

More Reading

Ionic: Using Factories and Web Services for Dynamic Data
Creating Views with Ionic
Controllers in Ionic/Angular

My name is Andrew McGivery. I currently work full time as an application developer at Manulife Financial in Canada. My current passion is building and leading highly engaged teams where employee happiness, learning, and growth is a priority.

80 Responses

  1. Hi Andrew.

    Thanks for the post.

    I managed to make it work, but it hangs when there is no connection. Is there any easy way to handle timeouts?

    • Hello Andreas,

      Thanks for your comment!

      One thing you can try is adding an error handler for when your promise resolves.

      Take for example the final example in my post:

      .controller('MainCtrl', function($scope, userService) {
      
      	userService.GetUsers().then(function(users){
      		$scope.users = users;
      	});
      
      })
      

      we can add a section parameter to our .then method for if something goes wrong.

      .controller('MainCtrl', function($scope, userService) {
      
      	userService.GetUsers().then(function(users){
      		$scope.users = users;
      	}, function(){
      		console.log("Something went wrong!");
      	});
      
      })
      

      Let me know if that helps. 🙂

      • Thanks for the reply.

        Actually I was facing two problems:

        The first one was related to timeouts. The library does not handle timeouts and the callback is never called in those cases. So I had to change the library and manually inserted a timeout there.

        The second problem was that there’s a bug (I think) when there is no connection available. I tested in my Ipad with airplane mode on and the library still executes the method “_onSendSoapRequest”. The solution was to, instead of only checking for “xmlHttp.readyState == 4” I also checked for “xmlHttp.status==200”.

        My full modifications are as follows:

        var requestTimer = setTimeout(function() {
        xmlHttp.abort();
        callback(null);
        }, 30000);
        var soapaction = ((ns.lastIndexOf(“/”) != ns.length – 1) ? ns + “/” : ns) + method;
        xmlHttp.setRequestHeader(“SOAPAction”, soapaction);
        xmlHttp.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);
        if(async)
        {
        xmlHttp.onreadystatechange = function()
        {
        if(xmlHttp.readyState == 4 && xmlHttp.status==200) {
        clearTimeout(requestTimer);
        SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
        }
        }
        }

        Note that I then call the callback with null, so I can check for null in your factory method and reject with a suitable message.

        After that, the second parameter of the .then method is called.

        I don’t know if this is the correct way, since I’m quite new in Javascript, but it’s working.

        • Hi Andreas, I am having the same problem when working offline, the callback is never fired, I tried your solution but I looks like I am missing something, could you please post the code you use to use the callback on the factory? and did you test with poor internet connection to see if the timeout handles the reject properly?

  2. Hi Andrew McGivery,

    Great tutorial, i tried the hello world sample and i got the below error

    GET http://192.168.3.19:8081/WebServiceExample/services/Test?wsdl 200 OK 16ms
    soapclient.js (line 145)
    ParamsHeadersXML
    XML Parsing Error: no element found Location: moz-nullprincipal:{61bef7ba-8608-40f4-9389-5a6fdf62be26} Line Number 1, Column 1:
    ^
    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://192.168.3.19:8081/WebServiceExample/services/Test?wsdl?wsdl. This can be fixed by moving the resource to the same domain or enabling CORS.

    TypeError: wsdl is null
    var ns = (wsdl.documentElement.attributes[“targetNamespace”] + “” == “undefined”…

    can you please help me how to resolve this

  3. Hi Andrew!

    Thanks for the post.

    I have WCF WebServices, I have a problem with the url base, because my URL base is
    var base_url = “http://mydomain/SoapTest/Service1.svc”;

    And this cause errors in the SOAPClient because it can’t resolve the .wsdl file.

    You can help me, please

  4. I am getting this error XMLHttpRequest cannot load https://localhost:9443/services/AuthenticationAdmin?wsdl. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:9000’ is therefore not allowed access.

  5. Hello! Very nice article and wrapper library. I have one question, though: Currently, it seems like the request method is GET. Is there a simple way to use POST instead? Not only does POST allow for bigger payloads, but some SOAP services require POST (like the one I’m integrating to…:-).

    • Hello Per Quested Aronsson!

      Thanks for your comment.

      As it turns out, the library only uses GET to get the WSDL and the request itself is always sent over POST. I have updated both the abstraction class on GitHub and this post accordingly. The get method of the abstraction is now post.

  6. Hi McGivery, You said For SOAP there is only one method “GET” But i want to call “POST”, How can i call POST method using SOAP srvices? Can you give example?

    Thank you.

    • Hello Sandeep!

      Thanks for your comment.

      As it turns out, the library only uses GET to get the WSDL and the request itself is always sent over POST. I have updated both the abstraction class on GitHub and this post accordingly. The get method of the abstraction is now post.

  7. Hi McGivery, I’m also getting wsdl null using the following wsdl url: http://0.0.0.0:8080/amxbpm/SecurityService, looking at the browser I can get the wsdl description with this url: http://0.0.0.0:8080/amxbpm/SecurityService?wsdl
    I’m getting this error, but I dont find the issue
    TypeError: wsdl is null
    [Break On This Error]

    … “undefined”) ? wsdl.documentElement.attributes.getNamedItem(“targetNamespace”)….

    • Have you checked developer tools to see if it is successfully making the GET request to the WSDL or not?

      • Yes it is successfully making the get request, I already solved it , it was a CORS issue, and we solved it by using a proxy on client server. Now we can make the request and we get a response but I’m having issue with the populating back to a variable in angularjs, the response is returning undefined as I think is returning the promise before it actually gets populated by response of the service.

        • Make sure you are not doing something like this:

          users = UserService.getAll();
          

          And instead doing something like this:

          UserService.getAll().then(function(data){
             users  = data;
          });
          
  8. Hi Andrew!

    Thanks for your post! I’m testing it but i obtained an error in callback function. Param ‘e’ is null. But call soap goes OK and my server answer good. What is the problem?

    Thanks in advance

  9. Hi again Andrew,

    Finally, i’ve corrected this issue with following:

    function GetSoapResponse_callBack(r, soapResponse)
    {

    deferred.resolve(soapResponse);

    }

    SOAPClient.invoke(url, action, soapParams, true, GetSoapResponse_callBack);

    • Mar,

      I am having the same issue. ‘e’ is null, but the server response is valid. Can you explain your solution a little more?

      The last line is replacing a line in angular.soap.js, but where are you placing the function above it and where is that being called?

      Thanks

      • Ran into same..

        Here’s what he did.

        //Create Callback
        /*
        var soapCallback = function(e){
        if(e.constructor.toString().indexOf(“function Error()”) != -1){
        deferred.reject(“An error has occurred.”);
        alert(‘there is an error’);
        } else {
        deferred.resolve(e);
        }
        }*/

        function GetSoapResponse_callBack(r, soapResponse)
        {

        deferred.resolve(soapResponse);

        }

        SOAPClient.invoke(url, action, soapParams, true, GetSoapResponse_callBack);

        I don’t know what r is. Put a break and debug, I spent too much time on this already.. Finally got it working..

        • Hi,

          I had the same problem and figured it out. The issue is in combination of soapclient.js and the wsdl file.

          In my case soapclient expected
          var nd = SOAPClient._getElementsByTagName(req.responseXML, method + “Result”);
          but my wsdl specified
          method + “Response”
          also be carefull with upper/lower case…

          If soapclient can’t find the expected node, the result (e) is null and as a second parameter it provides the raw xml data. So check line 198 in soapclient with the debugger, if you’re wsdl fits the expectation.

          By the way, thank you very much for this tutorial Andrew

  10. i have created my own web service and wsdl, I tried to call using code shared by you but i got following java error.

    [ERROR] The endpoint reference (EPR) for the Operation not found is /soap/services/Login?wsdl?wsdl and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
    org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /soap/services/Login?wsdl?wsdl and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.

    • Do you have an example of the code you are using? Make sure not to pass the ?wsdl part in when calling the service. It adds that for you.

  11. I need more details about SOAP Web Services in AngularJS. Can you help me. Thanks.

    • What do you need?

      • Hi, I am new to soap and AngularJS. I would like to know more details about both. For ex: how to create a dropdown list using AngularJS with soap server. Like FAQ.

      • I am new this course. How to write and where to write this code properly? can you give full demo please…

  12. Hi Andrew,
    I get a security in calling my service, so Iwould want to add a header in my request soap? How can I process using $soap variable?
    Thks

  13. Hi Andrew,

    Note that I am using angular.soap.js and not able to call web services. wsdl get retrieves ok, but next call is OPTIONS and that call crashes as bad request (400).

    This is the paste from the code, just like your example paste is from the factory:

    var base_url = “http://**********/CardService.svc”;

    return {
    CheckUserEx: function(userID){
    return $soap.post(base_url ,”CheckUserEx”, {userID: userID});
    }

    Do you have any idea why it is happening?

    Thank you,
    Zoran

  14. I got:
    XMLHttpRequest cannot load http://www.cooldomain.com/SoapTest/webservicedemo.asmx?wsdl. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8080’ is therefore not allowed access. The response had HTTP status code 404.

    Does anyone know, how I can fix it ?

  15. Hey Andrew, Great add-on for angular for sure, being stuck with just REST is a major issue for us. I have one problem though, all of the params we need to send to the web services are complex structures and I cannot figure out how to properly set them. The param structure always comes through to the server as null. I get back the response no problem, but no params are getting to the server.

    I have tried using the format the Javascript SOAP Client site shows, like this:

    var userLoginData = new Object();
    userLoginData.moduleName = “TIM”;
    userLoginData.siteId = “0”;
    userLoginData.userName = “pplan”;
    userLoginData.userPassword = “dba”;
    var p1 = new SOAPClientParameters();
    p1.add(“userLogin”, userLoginData);

    return {
    UserLogin: function()
    {
    return $soap.post(base_url,”UserLogin”,p1);
    }
    }

    That code results in p1 looking like:

    p1
    SOAPClientParameters {}add: (name, value)toXml: ()__proto__: SOAPClientParameters
    p1.toXml();
    “TIM0pplandba”

    I also tried just sending the object as the param with values like:

    userLogin
    Object {moduleName: “TIM”, siteId: “0”, userName: “pplan”, userPassword: “dba”}

    The WSDL segment looks like:

    The back end is using Java JAX-WS for the web services.

    Any thoughts or an example on how to get the params to the server would be greatly appreciated.

    • Hi Ed,
      Were you able to solve this?

      @Andrew: I am trying to send these parameters and it keeps saying Administrator is undefined.

      Here’s my code:

      var soap_parameters = “{ login: ‘Administrator’, password: ‘****’, resetState: true, refresh: true, getFromLatestDocumentInstance: true, getFromUserInstance: true, turnOutputToVTable: true, closeDocument: true, startRow: 1, endRow: 200 }”;

      return {
      GetAllFacilities: function () {
      return $soap.post(soap_url, soap_method, soap_parameters);
      }
      };

      • What I found out was causing my issue was the way the service request string was being built inside of the soapclient.js. Below is the code I am using and the original code (in soapclient.js about line 192):

        var sr =
        ‘ ‘
        + ‘ ‘
        + ‘ ‘
        + “” + parameters.toXml() + “”
        + ‘ ‘
        + ‘ ‘;
        //var sr =
        // “” +
        // “” +
        // “” +
        // “” +
        // parameters.toXml() +
        // “”;

        I took the XML code from another app we have that we are in the process of replacing to find out what was needed to meet our backend system. After changing that it was pretty simple to get the params correct, but took awhile to figure out it was a lower level operation that was causing the problem.

        The main difference is the “jsx1” prefixes our server side was expecting, not sure what they are for, but copying from a working system worked. If you debug your app to the creation of “sr” and can compare that to something that works, then you will probably find a difference.

        Hope that helps someone.

        • Sorry the comment editor seems to have whacked my JS code, so not sure how to get you what I actually used. Look for differences in your request string from somewhere else against the same web service and should be able to see the differences.

  16. Thanks nice post
    Last update of “JavaScript SOAP Client” was on – Dec 21, 2007 .

  17. When i use your code i took that error :
    Module “angularSoap” was created but never loaded.
    Module “myApp” was created but never loaded.

    Could you tell me what s wrong about it bro. I really need your code to fix my job.

    • Double check the order you are loading your scripts. Ionic/Angular should come first, then angularSoap, then your app code. Double check that you are importing the module in properly too.

  18. Yatish Mehta

    How do I handle timeouts, while its still resolving WSDL file.

  19. Hi Andrew,
    Thank you for your post, you have been very helpful!

    Although, I am getting an error:

    Error: $injector:unpr
    Unknown Provider

    Unknown provider: $soapProvider <- $soap <- CallService

    I can not find anything online about it
    What do you think might went wrong?

    Thank you

    • I am sorry I forgot to write the AngularSoap dependency in the module

  20. Hello, thanks for the article.
    I have a demo app in which I’d like to include the SOAP.
    I found the git archive and I downloaded but where i have to put the files ??

    Thanks!

    • Sorry for the (almost) silly question: i put them on js/ folder.

      I have other question: what if i need to have a GET request instead of the POST request?

      Tnx

  21. Hi Andrew,
    I am stucked with these three errors. Kindly help me out where and what I am doing wrong

    1. OPTIONS https://api.mindbodyonline.com/0_5/ClassService.asmx SOAPClient._sendSoapRequest @ soapclient.js:190SOAPClient._onLoadWsdl @ soapclient.js:153xmlHttp.onreadystatechange @ soapclient.js:142

    2. XMLHttpRequest cannot load https://api.mindbodyonline.com/0_5/ClassService.asmx. Invalid HTTP status code 405

    3. soapclient.js:331 Uncaught TypeError: Cannot read property ‘getElementsByTagName’ of nullSOAPClient._getElementsByTagName @ soapclient.js:331SOAPClient._onSendSoapRequest @ soapclient.js:198xmlHttp.onreadystatechange @ soapclient.js:187

    You can analyze the service here.
    https://api.mindbodyonline.com/0_5/ClassService.asmx?op=GetClasses

    Here is my code

    angular.module(‘MbApp’, [‘angularSoap’])
    .factory(“ClassService”, [‘$soap’, function ($soap) {
    var base_url = “https://api.mindbodyonline.com/0_5/ClassService.asmx”;

    return {
    GetClasses: function (d) {
    return $soap.post(base_url, “GetClasses”, {ClassDescriptionIDs:[],ClassIDs:[],StaffIDs:[], StartDateTime: d, EndDateTime: d,ClientID:[],ProgramIDs:[],SessionTypeIDs:[],LocationIDs:[1],SemesterIDs:[], HideCanceledClasses: true, SchedulingWindow: true });
    }
    }
    }])

    .controller(‘ClassController’, function ($scope,ClassService) {

    $scope.d = “2015-08-11”;
    ClassService.GetClasses($scope.d).then(function(response){
    $scope.response = response;
    });

    });

  22. Edgar Gomez

    The chrome developer tools shows me the next error

    Uncaught TypeError:
    Cannot read property ‘getElementsByTagName’ of nullSOAPClient._getElementsByTagName @ soapclient.js:331
    SOAPClient._onSendSoapRequest @ soapclient.js:198
    xmlHttp.onreadystatechange @ soapclient.js:187

  23. Hi Andrew McGivery,

    Great tutorial, i followed your tutorial and i got the below error

    TypeError: wsdl is null
    var ns = (wsdl.documentElement.attributes[“targetNamespace”] + “” == “undefined”…

    can you please help me how to resolve this

  24. Hi Andrew,

    i followed your tutorial but i got 500 error?
    and i really have no idea why i am getting this 500 error?

    i am new on angular.js and using magento soap web services.
    can you please help me to resolve this.

    • Did you check the Network Monitor in Dev Tools to see if the request being sent is what you are expecting and if the response contains any error messages?

  25. Thanks for sharing the best…

  26. Hi Andrew

    angular.module(‘starter.controllers’, [‘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(‘AppCtrl’, function($scope, $ionicModal, $timeout, testService) {

    // With the new view caching in Ionic, Controllers are only called
    // when they are recreated or on app start, instead of every page change.
    // To listen for when this page is active (for example, to refresh data),
    // listen for the $ionicView.enter event:
    //$scope.$on(‘$ionicView.enter’, function(e) {
    //});

    // Form data for the login modal

    testService.HelloWorld().then(function(response){
    console.log(“Response -> ” + response);
    $scope.response = response;
    });
    });

    It throws exception:

    Error: SOAPClientParameters is not defined
    .post@http://localhost:8100/js/angular.soap.js:9:8

    how to solve this?

  27. Hi Andrew,

    I am getting below exception:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.webservicex.net/globalweather.asmx?wsdl. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

    Please update me with the fix.

    thanks,
    Aleem

  28. Is there a way to set headers when using $soap.post ?
    In my case I need to add and authentication token in the headers.

  29. Fantastic, I can send headers now many thanks 🙂

    Of course that generates more questions…… how can I interrogate the headers in a response?

    eg.
    $soap.post(…)
    .then(function(responseObject){
    // get hold of response headers here somehow
    response.headers(“headerName”); // or something like that?
    })

    • Too soon….headers don’t seem to come through

      • Forget that, headers arriving on server, I had left the old ref to soapclient.js in config, which was causing problems. Removed that duplication and behaving better.

        Stil lneed to find a way to access response headers from server.

  30. Is there any way I can attach a file to SOAP request using this library?

  31. Hi Andrew McGivery . I’m trying to implement Saop webservice on my project and I’m getting this error when I run on Google Chrome. Can you please help me out.XMLHttpRequest cannot load , No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8100’ is therefore not allowed access.
    soapclient.js:157 Uncaught TypeError: Cannot read property ‘documentElement’ of null

    • You’re going to need to set up your server/endpoint to support CORS by heading it return the ‘Access-Control-Allow-Origin’ header with the response. Google the header name. Lots of courses out there.

  32. tarjeet singh

    Hey Andrew, First of all Thanks for the beautiful post .
    i am trying to access my Soap web service which has username and password requirement.

    .factory(“HHService”, [‘$soap’, function ($soap) {
    var base_url = “My Url”;

    //$soap.setCredentials(“username”, “Password”);
    return {
    SaveResultQuery: function (EmailAddress, ) {
    return $soap.post(base_url, “UpdateStatsSOAP”, { EmailAddress: EmailAddress });
    }
    }
    }])

    Thats the factory
    and then i invoke it like

    HHService.SaveResultQuery($rootScope.Email).then(function (data) {
    debugger
    });

    This opens up popup on app for Username and password
    can you please guide.

    Thanks
    Tarjeet SIngh

  33. Hi Andrew, nice post.
    I copy and i try your code and no works.
    I got a error, but i never stop in breakpoint of function callback. I tried with diferents web service, publics or mades for us. Ex: http://www.guru4.net/articoli/javascript-soap-client/demo/webservicedemo.asmx

    I use firefox and the response on wsdl is null. I obtein te GET with response HelloWord. Also is the OPTIONS but i don’t know how is this. The response is null

    etc…..
    But, i didn’t obtein te string HelloWorld with responseXML and i don’t show never in my html.

    Can you help me?

    Thanks.

  34. fadi alhamwi

    please i need help here !

    Am trying to get many object using $soap.post(base_url, “getRTLCities”, { passkey: passkey });

    but when i looked inside the response, i found one node in the returned object (the last one only ),

    • fadi alhamwi

      the object look like this :

      NewDataSet: Object
      RetailCities: Object
      rCity: “Yanbu”
      routCode: “YNB ”

      __proto__: Object
      __proto__: Object
      __proto__: Object

      i missing the remaining list of cities ,

    • Have you checked in dev tools to make sure the response is what you are expecting?

  35. Hi Andrew,

    Your post is really helpful. I’m new to Soap Webservice and AngularJS. I have created webservice using jax-ws. the Web service is working fine using with a local test client.

    running on my local mac with following the endpoint
    http://localhost:9999/ws/grocery
    Can access http://localhost:9999/ws/grocery?wsdl in the browser.

    However, using the angular.soap.js and soapclient.js: i had to change the $soap.post to $soap.post

    var herWebAppModule = angular.module(‘herWebApp’, [‘angularSoap’,’ngRoute’]);

    “herWebAppModule.factory(“ReportService”, [‘$soap’,function($soap){
    var base_url = “http://localhost:9999/ws/grocery”;

    return {
    getAllItems: function(){
    return $soap.get(base_url,”getAllItems”);
    }
    }
    }])

    .controller(‘MySoapController’, function($scope, ReportService) {

    ReportService.getAllItems().then(function(items){
    $scope.items=items;
    for(i=0;i<items.length;i++){
    console.log(items[i].name);
    console.log(items[i].shopName);
    }
    });

    })

    however, it resolved and then i got following error :

    http://localhost:9654/herWebApp/#/view/soaplist:1 XMLHttpRequest cannot load http://localhost:9999/ws/grocery?wsdl. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9654&#039; is therefore not allowed access.
    soapclient.js:158 Uncaught TypeError: Cannot read property 'documentElement' of nullSOAPClient._sendSoapRequest @ soapclient.js:158SOAPClient._onLoadWsdl @ soapclient.js:153xmlHttp.onreadystatechange @ soapclient.js:142

    i thought its CORS error: i even tried to enable in the my localtomcat using the filter. But still not working.

    If you can shed some light what wrong i'm doing.

    • Have you taken a look at the request/response in browser dev tools and made sure the ‘Access-Control-Allow-Origin’ header is coming back?

      • I’m running the the Web Service not in a web Container. I started the web service and from command line

        Using the curl command :

        curl -s -D – http://localhost:9999/ws/grocery?wsdl -o /dev/null
        HTTP/1.1 200 OK
        Date: Sat, 26 Mar 2016 21:55:52 GMT
        Transfer-encoding: chunked
        Content-type: text/xml;charset=utf-8

        I don’t see it on the Response header while making a request to WSDL.

        • I have even used the @CrossOrigin annotation in my End point publisher, considering that will enable the Access Control Allow-origin header
          org.springframework.web.bind.annotation.CrossOrigin;

          but no change. I must be doing something wrong fundamentally.

  36. Hi Andrew,

    Thanks for your tutorial.

    I have a little problem. When I launch my application and I’m not connect to internet and then I connect my smartphone to internet, I can’t have access to the web service. Have some informations about that ?

    Thanks a lot in advance

Leave a Reply