convert xml data into json in javascript - javascript

Need help to convert xml response data into json value and fetch a value from JSON object.
My current code is:
const soapRequest = require('easy-soap-request');
const fs = require('fs');
var convert = require('xml-js');
// example data
const url = 'https://sentro.com/ws/apf/ticketing/Gateway?WSDL';
const sampleHeaders = {
'user-agent': 'sampleTest',
'Content-Type': 'application/html;charset=UTF-8',
};
const xml = fs.readFileSync('Auto_query_request.txt', 'utf-8');
// usage of module
(async () => {
const { response } = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 1000 }); // Optional timeout parameter(milliseconds)
const { headers, body, statusCode } = response;
console.log(headers);
//console.log(body);
const options = {ignoreComment: true, alwaysChildren: true};
var result = JSON.parse(convert.xml2json(body, options));
console.log(result);
})();
When i executed above code , i am getting response like below.
{"declaration":{"attributes":{"version":"1.0","encoding":"UTF-8"}},"elements":[{"type":"element","name":"env:Envelope","attributes":{"xmlns:env":"http://schemas.xmlsoap.org/soap/envelope/","xmlns:wsa":"http://www.w3.org/2005/08/addressing"},"elements":[{"type":"element","name":"env:Header","elements":[{"type":"element","name":"wsa:MessageID","elements":[{"type":"text","text":"urn:5C8DC410D18D11EABFB75749E02F1482"}]},{"type":"element","name":"wsa:ReplyTo","elements":[{"type":"element","name":"wsa:Address","elements":[{"type":"text","text":"http://www.w3.org/2005/08/addressing/anonymous"}]},{"type":"element","name":"wsa:ReferenceParameters","elements":[{"type":"element","name":"instra:tracking.compositeInstanceCreatedTime","attributes":{"xmlns:instra":"http://xmlns.oracle.com/sca/tracking/1.0"},"elements":[{"type":"text","text":"2020-07-29T06:19:25.981-05:00"}]}]}]},{"type":"element","name":"wsa:FaultTo","elements":[{"type":"element","name":"wsa:Address","elements":[{"type":"text","text":"http://www.w3.org/2005/08/addressing/anonymous"}]},{"type":"element","name":"wsa:ReferenceParameters","elements":[{"type":"element","name":"instra:tracking.compositeInstanceCreatedTime","attributes":{"xmlns:instra":"http://xmlns.oracle.com/sca/tracking/1.0"},"elements":[{"type":"text","text":"2020-07-29T06:19:25.981-05:00"}]}]}]}]}
with the above results its very difficult for me to fetch data from JSON object.
So i need convert this xml body with proper JSON object as below.
{
"Header": {
"MessageID": "urn:45597DC0D1B511EA8F1C35236A977E2C",
"ReplyTo": {
"Address": "http://www.w3.org/2005/08/addressing/anonymous",
"ReferenceParameters": {
"tracking.compositeInstanceCreatedTime": "2020-07-29T11:05:06.880-05:00"
}
},
"FaultTo": {
"Address": "http://www.w3.org/2005/08/addressing/anonymous",
"ReferenceParameters": {
"tracking.compositeInstanceCreatedTime": "2020-07-29T11:05:06.880-05:00"
}
}
},
"Body": {
"processResponse": {
"payload": {
"RfcProject": {
"IntegrationStatus": "Query - Success",
"Id": "something query",
"Created": "2020-06-16T10:24:18",
"CreatedBy": "something",
"Updated": "2020-07-23T14:14:03",
"UpdatedBy": "somevalue",
"ProjectNum": "something",
and also how to fetch value from JSON Value .Can anyone help here

Related

CustomHook with multiple functions doesn't work

I am not sure why this customhook doesn't work , I am trying to make a payment Integration to my website but it doesn't return the frame to the other component so i can get the link , here is the code
import React , {useState} from 'react'
import { useEffect } from 'react';
export async function usePayment(data) {
const API = process.env.PAYMOB_API;
const integrationID = 2874212;
const [frame,setFrame] = useState('');
async function firstStep (datas) {
let data = {
"api_key": API
}
let request = await fetch('https://accept.paymob.com/api/auth/tokens' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
let response = await request.json()
let token = response.token
await secondStep(token , datas)
}
async function secondStep (token , datas) {
let data = {
"auth_token": token,
"delivery_needed": "false",
"amount_cents": datas.amount * 100,
"currency": "EGP",
"items": [],
}
let request = await fetch('https://accept.paymob.com/api/ecommerce/orders' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
let response = await request.json()
let id = response.id
await thirdStep(datas , token , id)
}
async function thirdStep (datas , token , id) {
let data = {
"auth_token": token,
"amount_cents": datas.amount * 100,
"expiration": 3600,
"order_id": id,
"billing_data": {
"apartment": "803",
"email": datas.email,
"floor": "42",
"first_name": datas.name,
"street": "Ethan Land",
"building": "8028",
"phone_number": "00000000000",
"shipping_method": "PKG",
"postal_code": "01898",
"city": "Jaskolskiburgh",
"country": "CR",
"last_name": "Nicolas",
"state": "Utah"
},
"currency": "EGP",
"integration_id": integrationID
}
let request = await fetch('https://accept.paymob.com/api/acceptance/payment_keys' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
let response = await request.json()
let TheToken = response.token
let iframURL = `https://accept.paymob.com/api/acceptance/iframes/377194?payment_token=${TheToken}`
setFrame(iframURL)
console.log(frame)
}
useEffect(() =>{
firstStep(data)
},[])
return { frame };
}
export default usePayment;`
I am not sure what is missing here , please need someone to guide me why multiple functions in customhook doesn't work , error message is
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1 - You might have mismatching versions of React and the renderer (such as React DOM)
2 - You might be breaking the Rules of Hooks
3 - You might have more than one copy of React in the same app
and this is the code i use to call the function :
const handleSubmit = async (event) => {
event.preventDefault();
try {
if ( !name || !email || !amount ) {
generateError("Please Fill The Form !")
} else {
const { frame } = await usePayment(datas);
console.log(frame)
// location.href = pay.iframURL;
}
} catch (err) {
console.log(err);
}
};
I expect to get a url to the frame state then pass it to another component
NOTE : that this functions works fine when i add it to the component but its not working as a customhook , i am not sure why
For this use case it would be better not to use a hook, rather just write this as a js function. There's no advantage I can see to using a hook, since you're just waiting for data in useEffect and invoking the 3 api calls after that. Instead just send the payload directly to the async function when needed.
const API = process.env.PAYMOB_API;
const integrationID = 2874212;
async function firstStep (data) {
let data = {
"api_key": API
}
let request = await fetch('https://accept.paymob.com/api/auth/tokens' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
const { token } = await request.json()
return token
}
async function secondStep ({token , data}) {
let data = {
"auth_token": token,
"delivery_needed": "false",
"amount_cents": data.amount * 100,
"currency": "EGP",
"items": [],
}
let request = await fetch('https://accept.paymob.com/api/ecommerce/orders' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
const { id } = await request.json()
return id
}
async function thirdStep ({data , token , id}) {
let data = {
"auth_token": token,
"amount_cents": data.amount * 100,
"expiration": 3600,
"order_id": id,
"billing_data": {
"apartment": "803",
"email": data.email,
"floor": "42",
"first_name": data.name,
"street": "Ethan Land",
"building": "8028",
"phone_number": "00000000000",
"shipping_method": "PKG",
"postal_code": "01898",
"city": "Jaskolskiburgh",
"country": "CR",
"last_name": "Nicolas",
"state": "Utah"
},
"currency": "EGP",
"integration_id": integrationID
}
let request = await fetch('https://accept.paymob.com/api/acceptance/payment_keys' , {
method : 'post',
headers : {'Content-Type' : 'application/json'} ,
body : JSON.stringify(data)
})
let response = await request.json()
let TheToken = response.token
let iframURL = `https://accept.paymob.com/api/acceptance/iframes/377194?payment_token=${TheToken}`
return frame;
}
}
export async function handlePayment(data) => {
const token = await firstStep(data);
const id = await secondStep({ data, token });
return await thirdStep({ data, token, id })
}
export default handlePayment;`

How to convert code from node.js to JavaScript

I need to rewrite an Api call. The original call is write in Node.js and i'm trying to rewrite the call in Javascript.
Node.js code:
const http = require("https");
const options = {
"method": "POST",
"hostname": "test.com",
"port": null,
"path": "/path",
"headers": {
"Authorization": "Token token-value"
}
};
const req = http.request(options, function (res) {
const chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(JSON.stringify({
data: {
'Id': 'id value'
},
responsive: false
}));
req.end();
I'm trying in this way:
const url='https://test.com/path'
const bodyContent = {
data: {
'Id': 'id value'
},
responsive: false
};
const options = {
"method":"POST",
"port":null,
"headers": {
"Authorization":"Token token-value"
},
body: JSON.stringify(bodyContent)
}
const res = await fetch(url, options)
I expected a positive response but the response keep saying "Missing value of required parameter 'Id'"

A property named "locale" in my API response body is being overridden in some browsers

I have an API returning this kind of payload in its response body:
{ "id": 1, "name": [{ "locale": "en", "value": "example" }] }
I'm calling this API using the following code in a React web app:
async function getAsync(url) {
return fetch(url, {
method: "GET",
mode: "cors",
credentials: "include",
headers: {
...commonHeaders, // Just for auth
},
})
}
async function getResponse() {
const url = `...` // API url
let res
try {
res = await getAsync(url)
switch (res.status) {
case 200:
const resBody = await res.json()
return Promise.resolve(resBody)
...
default:
return Promise.reject(new GenericError())
}
} catch (err) {
return Promise.reject(new GenericError())
}
}
The problem is the following: When I print in console JSON.stringify(resBody) I get the correct payload (of course as a JSON string), but if I print resBody its property name.locale has my locale ("it") instead of "en"!
Why is it happening? What's going on here???
This happens in both Firefox (85.0.2) and Chrome (88.0.4324.150) but NOT in Safari (14.0.2).
I've found the reason! It was a nasty side-effect present in a completely different asynchronous function in my UI, caused by these very wrong comparisons (please notice = used instead of ===):
{
name_en: name.filter(item => item.locale = "en").value || "",
name_it: name.filter(item => item.locale = "it").value || "",
}

How to put a buffer in an HTTP request?

I’m trying to put a buffer in a request because I have a list of data to import. I want to have success request after one another. The problem I’m encountering is that it waits to upload all data of the request.
Here is the sample data:
[
{
"contacts": "dsds#dsd.com",
"recipient": "dsd#dsd.com",
"date_sent": "07/08/2020 17:05:04",
"subject": "repurchase"
},
{
"contacts": "asd#ret.com",
"recipient": "test#yahoo.com",
"date_sent": "07/10/2020 17:31:51",
"subject": "biz"
},
{
"contacts": "we#sdf.com",
"recipient": "abc#yahoo.com",
"date_sent": "07/09/2020 13:02:54",
"subject": "rock"
}
];
const createEngage = async(body) => {
const BASE_URL = '/api/import'
var requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
"Content-Type": "application/json"
},
body: body
};
fetch(BASE_URL, requestOptions)
.then(response => response.text())
.then(async result => {
console.log(result);
})
.catch(error => console.log('error', error));
}
What you probably want to do is to loop over your data and use async / await to wait at each iteration. Your implementation of your asynchronous function currently does not await anything. Instead it should await the fetch request and the decoding of the body with response.text().
Check the response for errors and wrap the fetch request in a try...catch block. If an error occurs then the catch block will be executed. Otherwise check the response object for any states or errors you want to include.
const data = [
{
"contacts": "dsds#dsd.com",
"recipient": "dsd#dsd.com",
"date_sent": "07/08/2020 17:05:04",
"subject": "repurchase"
},
{
"contacts": "asd#ret.com",
"recipient": "test#yahoo.com",
"date_sent": "07/10/2020 17:31:51",
"subject": "biz"
},
{
"contacts": "we#sdf.com",
"recipient": "abc#yahoo.com",
"date_sent": "07/09/2020 13:02:54",
"subject": "rock"
}
];
const BASE_URL = '/api/import'
/**
* Sends a request for each individual item.
*/
const createEngage = async body => {
const requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body
};
try {
const response = await fetch(BASE_URL, requestOptions);
if (!response.ok) {
alert('Your request has failed');
return null;
}
const text = await response.text();
return text;
} catch(error) {
alert('Your request caused an error');
}
};
/**
* Loop over each item and call createEngage.
* Wait for the request to finish and continue.
*/
const createMultipleEngages = async data => {
for (const item of data) {
const result = await createEngage(item); // This will make the loop wait every time.
console.log(result);
}
};
// Call the function and start looping.
createMultipleEngages(data);

Elastic search Parser Error

I'm trying to construct the following search call in Javascript with no luck, the below works fine so I know my index is setup correctly in ES.
GET /teachersx9/teacher/_search
{
"query": {
"bool": {
"must": [
{ "match_all": {}},
{
"nested": {
"path": "langs",
"score_mode": "max",
"query": {
"bool": {
"must": [
{ "match": { "languagename": "Afrikaans"}}
]
}}}}
]
}}}
However, when trying to create the query on my server using:
app.get('/search', function(req, res) {
var term = req.query.term;//req.param('term');
var urlPath = 'https:.../teachersx9/teacher/_search';
//var obj = {};
var query = {};
query.bool = {};
var match_all = {};
var nested = {path:"langs", score_mode:"max"};
nested.query = {};
nested.query.bool = {};
nested.query.bool.must = [{match: {languagename:term}}];
query.bool.must = [{match_all:match_all}, {nested:nested}];
console.log(query);
request.post({
url: urlPath,
json: true,
body: query
}, function(error, response, body){
if (!error && response.statusCode == 200) {
console.log(body);
res.send(body);
} else {
console.log(body);
res.send(response);
}
});
});
Error I get back from ES as part of the response:
"statusCode": 400,
"body": {
"error": "SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[FMwFQZmkIAfOE7X48Q][teachersx9][0]: RemoteTransportException[[Quentin Quire][inet[/172.31.7.165:9300]][indices:data/read/search[phase/query+fetch]]]; nested: SearchParseException[[teachersx9][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"bool\":{\"must\":[{\"match_all\":{}},{\"nested\":{\"path\":\"langs\",\"score_mode\":\"max\",\"query\":{\"bool\":{\"must\":[{\"match\":{\"languagename\":\"Italian\"}}]}}}}]}}]]]; nested: SearchParseException[[teachersx9][0]: from[-1],size[-1]: Parse Failure [No parser for element [bool]]]; }]",
"status": 400
},
bool isn't a valid top-level construct in the Elastic query DSL. You need to wrap it in query.
var body = { query: query }
request.post({
url: urlPath,
json: true,
body: body
})

Categories

Resources