I am working on a solution where the web server (node with express) will be using request package to fetch data from a web api.
The data return (if contains validation error status code), will be matched again the value and return the corresponding error message. How could it be achieve?
It would be something like this:
var options = {
method: 'POST',
url: 'apiUrl'
}
var response = function (error, response, body) {
if(!error && response.statusCode == 200){
res.jsonp(body);
} else {
if (body.language == 'en') {
// map the reponse body error status code to en.json
} else if (body.language == 'jp')
// map the response body error status code to jp.json
}
}
request({
options, response
})
Default body response for validation error
{
'language': 'en',
'error': [{ 'ErrorCode': '1000', 'ErrorCode': '1001'}]
}
Final body response (after processing)
{
'language': 'en',
'error': [{'ErrorMessage': 'Invalid data format', 'ErrorMessage': 'Invalid Password'}]
}
Resource file for different language of validation (static in server)
en.json
{
'1000': 'Invalid date format',
'1001': 'Invalid password',
'1002': ...
'1003': ...
...
'1999': ...
}
jp.json
{
'1000': 'japan translation',
'1001': 'japan translation 2',
'1002': ...
'1003': ...
...
'1999': ...
}
Here you see how to it.
I'm using fs module to open the JSON file. and I'm using map to convert the errorCode array to errorMessage array
var response = function(error, response, body) {
if (!error && response.statusCode == 200) {
res.jsonp(body);
} else {
// Set defaut language.
if (!body.language.match(/en|jp|iw/)) body.language = 'en'
// You must specify default language for security reasons.
// Open the file, and convert to JSON object
var j = JSON.parse(
require('fs').readFileSync(__dirname + '/' + body.language + '.json')
)
res.jsonp({
language: body.language,
// Convert error:[{errorCode}] array to the messages from the JSON
error: body.error.map(function(v) {
return j[v.ErrorCode]
})
})
}
}
Related
I'm trying to ask for a confirmation before upload the file so the server, currently I have this HTML code:
<p-fileUpload mode="basic" name="file" url="{{urlUpload}}" chooseLabel="Upload CSV (onBeforeSend)="onBeforeSend($event)">
Then, I have this TS code:
onBeforeSend (event): void {
const token = this.service.getTokenSession();
event.xhr.setRequestHeader('Authorization', 'Bearer ' + token);
this.confirmationService.confirm({
message: 'Are you sure to continue?',
header : 'Confirmation',
accept : () => {
this.service.showLoader();
this.onUpload(event);
},
reject: () => {}
});
}
onUpload(event): void {
this.msgsPage = [];
try {
const response = JSON.parse(event.xhr.response);
console.log(response)
if (!response.ok) {
this.errorModalService.show('There was an error');
this.flagResultLoadErrors = true;
let c = 0;
for (let msg of response.map.errors) {
c++;
this.msgsPage.push({
detail : msg,
severity: 'error',
summary : 'Error ' + c,
});
}
}
} catch (e) {
this.errorModalService.show('Unknown error');
console.log(e)
} finally {
this.service.hideLoader();
}
}
With this, I tried to block the request, but it didn't happen, what I got is that the file is sent to the server before the confirmation dialog.
Also, I'm getting this error when I tried to get the response:
SyntaxError: Unexpected end of JSON input
Hope you can help me.
You can't block from that event. It is just an event emitted from the component.
https://github.com/primefaces/primeng/blob/master/src/app/components/fileupload/fileupload.ts#L367
You will need to use the custom uploadHandler.
<p-fileUpload name="myfile[]" customUpload="true" (uploadHandler)="myUploader($event)"></p-fileUpload>
myUploader(event) {
//event.files == files to upload
}
SyntaxError: Unexpected end of JSON input
This one means the response you are getting from the xhr response is not JSON, but you are trying to parse it. Check network tab to see what the response from the server is.
I am receiving below response from a service
[ { recipient_id: 'default',
text: 'Hello, how can I help?' } ]
I need to retrieve the text portion of the response. I can do that with python like below
json_response = response.json()
reply = json_response[0]['text']
But I need to retrieve the text portion in NodeJS now for a different project. So I have tried below code but it outputs undefined
var obj = JSON.parse(response)
console.log(obj[0]['text'])
Can anyone please suggest?
EDIT:
The POST request is made like
request.post(
'http://path-to-service',
{ json: { 'query': msg} },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
var obj = JSON.parse(body)
console.log(obj[0]['text'])
}
The problem is the service returns response as an array of python dictionary. So response[0] is essentially a python dictionary
{ recipient_id: 'default',
text: 'Hello, how can I help?' }
So the question is, how do I retrieve the value of the key text from this dictionary.
I think your response is already coming as JSON object so don't need to parse again.
var obj = [ { recipient_id: 'default',
text: 'Hello, how can I help?' } ];
console.log(obj[0].text);
try code
var body = {'query': 'msg', 'name': 'my name is nodejs'}
var obj = JSON.parse(body);
console.log(obj.query);
console.log(obj.name);
printf
msg
my name is nodejs
I'm accessing an api and I generated using NSwagStudio a type script version of the api calls to use as services. I get the response from the server and seems to work fine, but I don't know how to access the json file with the response. I tried subscribing to the method that I'm calling but I always get null as a response. Any help or guidelines will be appreciated it.
Here is an example of the code generated by NSwagStudio and my implementation to subscribe to the response.
apiSubmissionGetResultMessageGet(...) {
protected processApiSubmissionGetResultMessageGet(response: HttpResponseBase): Observable<void> {
const status = response.status;
const responseBlob =
response instanceof HttpResponse ? response.body :
(<any>response).error instanceof Blob ? (<any>response).error : undefined;
let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
if (status === 200) {
return blobToText(responseBlob).flatMap(_responseText => {
return Observable.of<void>(<any>null);
});
} else if (status !== 200 && status !== 204) {
return blobToText(responseBlob).flatMap(_responseText => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Observable.of<void>(<any>null);
}
}
And this is where I'm trying to subscribe:
getSubmissionDetails(string): void {
this.client.apiSubmissionGetSubmissionDocumentGet('documentId')
.subscribe(
data => {
this.submissionList = this.submissionList;
console.log('data: ', data);
},
(error: any) => this.errorMessage = <any> error);
}
The return type is Observable<void> which means that it doesnt return anything...
Check that the operation has a response type in the swagger spec and regenerate.
I am using NodeJS request module to pass a JSON request to a URL and generate a JSON response from it. I tried this code and it generates a valid response. I am pasting the link for a StackOverflow question I asked for the same.
NodeJS Request returning an empty array inside a JSON response
However, when I utilize the same logic in AWS Lambda, there is no response at all from the module. Since there is no response at all, I cannot understand what the problem is.
This is the handling function for the AWS Lambda with Alexa as a trigger.
'use strict';
var request = require('request');
var accountNumberRequest = {};
var balanceResponse = {};
const url = "https://ibluatapig.indusind.com/app/uat/balinq/AccountEnquiry?client_id=6867b781-9b21-45c5-9c55-948f7cd1a33f&client_secret=hP3yB3hM2oH4pH4hM1kV3uY8vR3qV7jY8cF6bG2sF5jX8lT1vN";
var bal = {};
exports.handler = function (event,context) {
try{
console.log("Try Started");
var req = event.request;
console.log("Request Generated");
if(req.type === "LaunchRequest") {
console.log("Launch Request! Calling handleLaunchRequest");
handleLaunchRequest(context);
} else if(req.type === "IntentRequest") {
console.log("IntentRequest");
let options = {};
console.log(0);
if(req.intent.name === "BalanceIntent") {
console.log("Balance Intent");
//Got the account number from Alexa request
let accNo = req.intent.slots.AccountNumber.value;
console.log(accNo);
accountNumberRequest = {
"AERequest":{
"serviceType":"BE",
"deviceId":"Test",
"accountId":accNo
}
};
console.log(accountNumberRequest);
console.log("Calling NodeJS.Request");
request({
url: url,
method: "POST",
json: true,
header: {
"content-type": "application/json",
},
body: accountNumberRequest
},
function(error, response,body){
if(!error && response.statusCode === 200){
console.log(body.AEResponse.AcctBal[1].BalAmt);
} else {
//options.speechText = `The account <say-as interepret-as = "digits">${accNo}</say-as> does not exist`;
console.log("error: "+error);
console.log("response.statusCode"+response.statusCode);
console.log("response.statusText"+response.statusText);
}
}
);
console.log("Balance Response should be assigned by now");
console.log(bal);
/* if(accountNumbers.hasOwnProperty(accNo)) {
var balance = accountNumbers[accNo];
accountExists = true;
}
if(accountExists == true){
options.speechText = `The balance of account number <say-as interpret-as = "digits">${accNo}</say-as> is <say-as interpret-as = "cardinal">${balance}</say-as>`;
} else {
options.speechText = `The account <say-as interepret-as = "digits">${accNo}</say-as> does not exist`;
}*/
context.succeed(buildResponse(options));
}
} else if(req.type === "SessionEndedRequest") {
//Code here
} else {
throw("Unknown Intent Type");
}
} catch(e){
context.fail("Exception "+e);
}
};
function getBalance(){
//Code to parse the JSON response and extract values from the response.
}
function handleLaunchRequest(context){
//Code for handling launch requests }
function buildResponse(options){
//Code for generating response
}
This is the problem...
// You're sending an asynchronous HTTP request here.
request();
// But you sent the response here without waiting for the above request to finish.
context.succeed();
Basically, you're executing context.succeed() before request() finishes. So you're basically ending your Lambda invocation without the response from that HTTP request.
To fix your code, put the context.succeed() inside the callback that you pass to the request() call.
P.S.
You should be using callback instead of the deprecated context.succeed()/context.fail() API.
I am creating a website that reads externally hosted json files and then uses node.js to populate the sites content.
Just to demonstrate what I'm after, this is a really simplified version of what I'm trying to do in node.js
var ids = [111, 222, 333];
ids.forEach(function(id){
var json = getJSONsomehow('http://www.website.com/'+id+'.json');
buildPageContent(json);
});
Is what I want to do possible?
(Marked as a duplicate of "How do I return the response from an asynchronous call?" see my comment below for my rebuttal)
You are trying to get it synchronously. What you should aim for instead, is not a function used like this:
var json = getJSONsomehow('http://www.website.com/'+id+'.json');
but more like this:
getJSONsomehow('http://www.website.com/'+id+'.json', function (err, json) {
if (err) {
// error
} else {
// your json can be used here
}
});
or like this:
getJSONsomehow('http://www.website.com/'+id+'.json')
.then(function (json) {
// you can use your json here
})
.catch(function (err) {
// error
});
You can use the request module to get your data with something like this:
var request = require('request');
var url = 'http://www.website.com/'+id+'.json';
request.get({url: url, json: true}, (err, res, data) => {
if (err) {
// handle error
} else if (res.statusCode === 200) {
// you can use data here - already parsed as json
} else {
// response other than 200 OK
}
});
For a working example see this answer.
For more info see: https://www.npmjs.com/package/request
I think problem is in async request. Function will return result before request finished.
AJAX_req.open( "GET", url, true );
Third parameter specified async request.
You should add handler and do all you want after request finished.
For example:
function AJAX_JSON_Req( url ) {
var AJAX_req = new XMLHttpRequest.XMLHttpRequest();
AJAX_req.open( "GET", url, true );
AJAX_req.setRequestHeader("Content-type", "application/json");
AJAX_req.onreadystatechange = function() {
if (AJAX_req.readyState == 4 && AJAX_req.status == 200) {
console.log(AJAX_req.responseText);
}
};
}