# ANG SOAP

This module provides the most reliable SOAP client. It is based on ``axios`` http client and ``fast-xml-parser``, so you can customise and parse your request and response the way you want.

## How to use

```javascript
const SoapClient = require('ang-soap');

const url = 'https://example.com/yourService';

const options = { axios: { timeout: 5000 } };// See Default options section for more details.

const client = new SoapClient(options);
// you can use the default options as well, without parameters
// const client = new SoapClient();
client.setBasicAuthSecurity('usernameXXX', 'passwordXXX');

const data = {}; // here your json using fast-xml-parser format. For more details, see data section
try {
    const res = await client.performRequest(url, data);
} catch (error) {
    console.log(error); // See Error section
}
```

## To enable and disable SSL, use:
```javascript
client.enableSSL();
client.disableSSL();
```
By default, SSL is activated.

## Url


> **WARNING**:  The url refers to the target SOAP API. This module does not use ``WSDL``.

```javascript
const url = 'https://example.com/yourService';
```
## Default options 

```javascript
const options = {
    axios: {
        method: 'POST',
        headers: { 'Content-Type': 'application/soap+xml', Accept: '*/*' }
    },
    fastXmlParser: {
        jsonParser: {
            attributeNamePrefix: '@_',
            attrNodeName: false,
            textNodeName: '#text',
            ignoreAttributes: false,
            cdataTagName: '__cdata',
            cdataPositionChar: '\\c',
            format: true,
            indentBy: '  ',
            supressEmptyNode: true,
        },
        xmlParser: {
            attributeNamePrefix: '',
            attrNodeName: false,
            textNodeName: '#text',
            ignoreAttributes: false,
            ignoreNameSpace: true,
            allowBooleanAttributes: false,
            parseNodeValue: false,
            parseAttributeValue: false,
            trimValues: false,
            cdataTagName: false,
            cdataPositionChar: '\\c',
            parseTrueNumberOnly: true,
            arrayMode: false, // "strict"
            stopNodes: ['parse-me-as-string'],
        },
    },
    jsonPath: '',
    debug: false,
    isRequestDataXML: false,
    isResponseXML: false
};
```
## Data

This is an example of data you pass as a parameter to ``performRequest()`` method :
```javascript
const data = {
    'soap12:Envelope': {
        '@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
        '@_xmlns:xsd': 'http://www.w3.org/2001/XMLSchema',
        '@_xmlns:soap12': 'http://www.w3.org/2003/05/soap-envelope',
        'soap12:Body': {
            ParentElement1: {
                '@_xmlns': 'http://www.namespace1.com',
                ChildElement : 'ElementValue',
            },
        },
    },
}
```
For more details about making and configuring the JSON parser, see ``fast-xml-parser`` node module.
### XML instead of JSON
You can also send an XML data instead of JSON. In this case, you need to set ``options.isRequestDataXML`` to ``true``
The data should be as follow:
```javascript
const data = `<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                <soap12:Body>
                    <ParentElement1 xmlns="http://www.namespace1.com">
                        <ChildElement>ElementValue</ChildElement>
                    </ParentElement1>
                </soap12:Body>
              </soap12:Envelope>`;
```
If you need a raw response, set ``options.isResponseXML`` to `true`


## Parsing the response
### jsonPath
When you call multiple SOAP methods, each response probably has its own data structure. So if you use the ``jsonPath`` option, you may need to set it before performing each request.
```javascript
const jsonPath = `$..Envelope.Body.YourTargetObject`;
client.setJsonPath(jsonPath);
```
For more details about ``jsonPath`` pattern, you can check the ``jsonpath`` node module.
### arrayMode
By default,``arrayMode`` is ``false``. A tag with single occurrence is parsed as an object but as an array in case of multiple occurences.
If you need to parse a specific tag as array only, you can set the option ``arrayMode`` using the following method:
```javascript
const targetTag = `/^yourTagName$/`; 
client.setArrayMode(targetTag);
```
In the previous case, the ``setArrayMode()`` method accepts a regex. To learn more about ``arrayMode`` option, see `fast-xml-parser` node module.

## Error 

When you catch an error, it will be in this format:
```javascript
{   
    message: <String>,
    error: <Error>
}
```

## Debug

If you want to follow all the steps from creating the request to receiving the response, set ``options.debug`` to `true`.
When ``debug`` is activated, you find in the console the result for each step.
