9

Im starting a new web application project with simple HTML, CSS and Angular. We are using existing Web Services to retrieve data from some servers, one service we are trying to use is a public service: Global Weather SOAP Service

Is there an "easy" way to make the request with Angular? Actually our "test" code is this (with JQuery, still does not work), but would be better to implement the Angular approach with HTTP or RxJS...

import { Injectable } from '@angular/core';
import * as $ from 'jquery';

@Injectable()
export class SoapServiceProvider {

    constructor() { }

    testingSoapRequest() {

        $.ajax({
            url: 'http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry',
            data: { CountryName: 'Spain' },
            success: (data) => {
                console.log('Hey, we got a success response', data);
            },
            error: (err) => {
                console.error('We got an error :(', err);
            }
        });

    }

}

I have never used JQuery to make requests of any type (I just use $http in AngularJS and RxJS with Angular), so I really don't know the correct way to make it possible.

Note: There is a library to make Angular SOAP Requests in GitHub but it seems that does not work anymore with new Angular versions.

This is the GitHub Autopulous SOAP link...

1
  • 2
    Angular has HttpModule for REST calls similar to JQuery Ajax Calls, you may read more about it here Commented Jun 8, 2017 at 17:08

2 Answers 2

1

First of all, don't use jQuery, Angular provides you with everything you need out of the box and it's faster and usually more powerful too.

Here's an example Ionic Page, making http requests:

import {Page, Alert, NavController} from 'ionic/ionic';
import {Http} from 'angular2/http';

@Page({
    templateUrl: 'build/pages/home/home.html',
})

export class HomePage {
    constructor(http: Http, nav: NavController) {
        this.http = http;
        this.nav = nav;
    }

    makeGetRequest() {
        this.http.get("https://httpbin.org/ip")
        .subscribe(data => {
            var alert = Alert.create({
                title: "Your IP Address",
                subTitle: data.json().origin,
                buttons: ["close"]
            });
            this.nav.present(alert);
        }, error => {
            console.log(JSON.stringify(error.json()));
        });
    }

    makePostRequest() {
        this.http.post("https://httpbin.org/post", "firstname=Nic")
        .subscribe(data => {
            var alert = Alert.create({
                title: "Data String",
                subTitle: data.json().data,
                buttons: ["close"]
            });
            this.nav.present(alert);
        }, error => {
            console.log(JSON.stringify(error.json()));
        });
    }
}

That logic could be hooked up to a simple template like this one:

<ion-navbar *navbar>
    <ion-title>
        Home
    </ion-title>
</ion-navbar>

<ion-content class="home">
    <button (click)="makeGetRequest()">GET Request</button>
    <button (click)="makePostRequest()">POST Request</button>
</ion-content>

Now since you are using SOAP messaging, you will need to convert JSON to SOAP compatible XML and similarly deconstruct it when you get a response.

I strongly advise you not to use SOAP because, despite the fact that it's an older tecnology, messages are much larger due to more verbose code needed to annotate the same data and most importantly, converting JSON -> XML is slow, especially in Javascript.

That being said, here's a very popular library to convert between the two types.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @maninak, this is my code to consume another SOAP Service but still does not work. ` this.http .post('localhost:9000/OurService.svc', '{ login="testUser", password="pwd123", deviceType="iOS" }', options) .subscribe(data => { console.log('Success post...', JSON.stringify(data)); }, error => { console.log('Error :(', error); }); ` The error i'm getting is 404 Not found. Is there a way to specify the Web Method to invoke?
@JuanJoseAdan You are getting a 404 because there is an error at the url and by that I mean localhost:9000/OurService.svc/. Which means that the networking part of the request is functioning properly. So if my answer has covered your question please mark it answered to close it.
@maninak but you are not consuming a SOAP service, which was the req; you are consuming a JSON one.
1

Yes - there is a way to consume SOAP services in Angular; no third party packages or libraries required. In a nutshell, you set the response type as text, construct an XML document out of the XML text, and (if desired) parse the XML document into JSON format.

Working demo: https://stackblitz.com/edit/angular-soap-test

Here are the steps using Angular 8, although they should also work (or be nearly identical) for Angular 2+:

  1. Request the SOAP resource as text:
     import { HttpClient, HttpParams } from '@angular/common/http';
     import { map } from 'rxjs/operators';

     // ...
     const params = new HttpParams();
     params.set('firstName', 'Peter');
     params.set('lastName', 'Parker');        

     this.http.get(YOUR_SOAP_SERVICE_URL, {responseType: 'text', params })
         .pipe(
           map((xmlString: string)=>{
             const asJson = this.xmlStringToJson(xmlString);
             return asJson;
           }),
           catchError((err)=> {
             console.warn('INT ERR:', err);
             return err;     
           })
         );
  1. Build an XML document out of the JSON string
    xmlStringToJson(xml: string)
    {
      const oParser = new DOMParser();
      const xmlDoc = oParser.parseFromString(xml, "application/xml");
  1. Convert the XML document to JSON
    /* xmlStringToJson(xml: string) */
    // ...
    return this.xmlToJson(xmlDoc);
  }

  // ...

  /**
   * REF: https://davidwalsh.name/convert-xml-json
   */
  xmlToJson(xml)
  {
    // Create the return object
    var obj = {};

    if (xml.nodeType == 1) { // element
      // do attributes
      if (xml.attributes.length > 0) {
      obj["@attributes"] = {};
        for (var j = 0; j < xml.attributes.length; j++) {
          var attribute = xml.attributes.item(j);
          obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
        }
      }
    } else if (xml.nodeType == 3) { // text
      obj = xml.nodeValue;
    }

    // do children
    if (xml.hasChildNodes()) {
      for(var i = 0; i < xml.childNodes.length; i++) {
        var item = xml.childNodes.item(i);
        var nodeName = item.nodeName;
        if (typeof(obj[nodeName]) == "undefined") {
          obj[nodeName] = this.xmlToJson(item);
        } else {
          if (typeof(obj[nodeName].push) == "undefined") {
            var old = obj[nodeName];
            obj[nodeName] = [];
            obj[nodeName].push(old);
          }
          obj[nodeName].push(this.xmlToJson(item));
        }
      }
    }
    return obj;
  }

2 Comments

nice, but how do you pass parameters to the soap service?
@MarcosGalaviz good question! Updated to add support for request parameters. REF: angular.io/guide/http#configuring-http-url-parameters

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.