Reputation: 135
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...
Upvotes: 9
Views: 38857
Reputation: 2695
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+:
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;
})
);
xmlStringToJson(xml: string)
{
const oParser = new DOMParser();
const xmlDoc = oParser.parseFromString(xml, "application/xml");
/* 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;
}
Upvotes: 1
Reputation: 2726
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.
Upvotes: 1