Node.js ERROR: (node:9748) UnhandledPromiseRejectionWarning: Unhandled promise rejection - json

I'm trying to get a json from "nightmare" in Node.js and then use JSON.parse(), but I'm getting the following error:
(node:9748) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: Unexpected token ☻ in JSON at position 18509
My code:
var nightmare = Nightmare()
.goto('URL')
.wait(10000) // Need wait some time
.evaluate(() => {
return document.body.innerText;
})
.end()
.then((body) => {
var data;
try {
data = JSON.parse(body);
} catch(e) {
console.log(e);
}
callback(null, data);
});

You can check if the JSON is valid or not simply using the JSON.parse function as you are using.
function validJSON(str) {
try {
// try to parse the JSON
JSON.parse(str);
} catch (e) {
// if not a json
return false;
}
// if it's valid json
return true;
}
It'll check if the string is valid json or not. Now, you can use it with your nightmareJS.
const nightmare = Nightmare()
.goto("URL")
.wait(10000) // Need wait some time
.evaluate(() => {
return document.body.innerText;
})
.end()
.then(body => {
// if it's a valid json, send it,
// otherwise send it as a body object
const data = validJSON(body) ? body : { body };
callback(null, data);
});
Now, the error is showing because you said to catch(e) and console.log(e) the error. Thus it's simply obeying your command.
Since the emoji itself is not a valid json, you have to either make a json from it, or parse it if it was a json string.
A valid json object might look like this,
{emoji: "☻"}
You see how it's all quoted?

Related

How to ask a confirmation before uploading a file (primeng)?

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.

solving the error 'Unexpected token < in JSON at position 0 at JSON.parse'

I deployed my angular 6 app to Heroku ( https://angulardictionary.herokuapp.com/).
But I'm getting the error SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse.
I understand what this error means: The response returns html instead of JSON.
My question is: how can I fix it?
I tried:
res.send(object)
res.json(object)
Here's my code:
server.js
app.get('*', function(req,res) {
res.sendFile(path.join(__dirname +'/dist/frontend/index.html'));
});
app.get('/api/words', function(req, res){
fs.readFile('newWords.xml', 'utf-8', function (err, data){
if(err){
console.log('error');
//res.send(err);
} else{
parser.parseString(data, function (err, result) {
let words = result['entry']['form'];
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(words));
web.service.ts:
getWords(name: string, option: any):Observable<Word[]>{
return this.http.get<Word[]>('/api/words',{
params: {
name:name,
option:option
}
}
);
}
and I call this function in: home.component.ts:
getWordList(){
this.webservice.getWords(this.spelling, this.selected)
.subscribe((res: Array<Word>)=> {
this.elements = res.filter(d=> d.orth == this.spelling || d.asuddimIsem
== this.spelling);
}
}
It seems as if all the http calls go directly to the default route (app.get('*', function(req,res)), skipping (app.get('/api/words')).
It seems as if all the http calls go directly to the default route (app.get('*', function(req,res)), skipping (app.get('/api/words')) this is correct. The order in which routes are defined matters. You have to put the wildcard * route at last. As for the other API, you may not need to stringify JSON.stringify() the response, you can simply do res.send(words).

Unexpected token < in JSON at position 1 ----ionic3

The data can be inserted into the database and the JSON also can be generated very well but why is 'Unexpected token < in JSON at position 1' thrown?
The problem has been shown in the picture
signup.ts
signup(){
this.authService.postData(this.userData,'signup').then((result) => {
this.responseData = result;
if(this.responseData.userData){
console.log(this.responseData);
localStorage.setItem('userData', JSON.stringify(this.responseData));
this.navCtrl.push(LoginPage);
}
else{ {swal({
title: "User already exist.Please try again",
})
} }
}, (err) => { ;
// Error log
});
}
You're getting BR tag in your response, and because of that it can't be parsed to JSON, so remove the
> <br />batman2#gmail.comhere
tag from your response.
You can validate JSON response in your service by using rxjs map operater:
this.http.get(YOUR_URL).map(res => res.json());

JSON returning with "\" (Lambda)

I am using AWS Lambda to get JSON from the open weather api and return it.
Here is my code:
var http = require('http');
exports.handler = function(event, context) {
var url = "http://api.openweathermap.org/data/2.5/weather?id=2172797&appid=b1b15e88fa797225412429c1c50c122a";
http.get(url, function(res) {
// Continuously update stream with data
var body = '';
res.on('data', function(d) {
body += d;
});
res.on('end', function() {
context.succeed(body);
});
res.on('error', function(e) {
context.fail("Got error: " + e.message);
});
});
}
It works and returns the JSON, but it is adding backslashes before every " like so:
"{\"coord\":{\"lon\":145.77,\"lat\":-16.92},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"}],\"base\":\"cmc stations\",\"main\":{\"temp\":303.15,\"pressure\":1008,\"humidity\":74,\"temp_min\":303.15,\"temp_max\":303.15},\"wind\":{\"speed\":3.1,\"deg\":320},\"clouds\":{\"all\":75},\"dt\":1458518400,\"sys\":{\"type\":1,\"id\":8166,\"message\":0.0025,\"country\":\"AU\",\"sunrise\":1458505258,\"sunset\":1458548812},\"id\":2172797,\"name\":\"Cairns\",\"cod\":200}"
This is stopping my over service using (SwiftJSON) detecting this as valid JSON.
Can anyone tell me how to make the API information come out as correctly formatted JSON?
I tried .replace like so:
res.on('end', function() {
result = body.replace('\\', '');
context.succeed(result);
});
It did not change anything. Still had the same output.
You're posting it as a string.
Try context.succeed(JSON.parse(result))
From the docs
The result provided must be JSON.stringify compatible. If AWS Lambda fails to stringify or encounters another error, an unhandled exception is thrown, with the X-Amz-Function-Error response header set to Unhandled.
http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
So essentially it's taking your json string as a string and calling JSON.stringify on it...thus escaping all the quotes as you're seeing. Pass the parsed JSON object to succeed and it should not have this issue
In case of Java, just return a JSONObject. Looks like when returning string it is trying to do some transformation and ends up escaping all the quotes.
If using Java, the response can be a user defined object as below
class Handler implements RequestHandler<SQSEvent, CustomObject> {
public CustomObject handleRequest(SQSEvent event, Context context) {
return new CustomObject();
}
}
Sample code can be found here.
Do this on your result: response.json()
You can use:
res.on('end', function() {
context.succeed(body.replace(/\\/g, '') );
To replace \ with nothing..

Why won't my req.flash work?

Here's a Node.js function. It works, in the sense that bad JSON data is kicked out, but it also flashes the message that it failed. Why?
// Create document
app.post('/documents.:format?', loadUser, function(req, res) {
/////////////////////////added by adam
//tests to see if the inputed text is valid JSON data
data = req.body.d.data;
console.log("///////////" + data);
try {
type = JSON.parse(data);
console.log(type);
} catch (ex) {
console.log("bad json: "+data);
req.flash('Nope', 'Invalid JSON');
res.redirect('/documents');
return;
}
var d = new Document(req.body.d);
d.user_id = req.currentUser.id;
d.save(function() {
switch (req.params.format) {
case 'json':
res.send(d.toObject());
break;
default:
req.flash('info', 'Document created');
res.redirect('/documents');
}
});
The catch block contains both the error message and the 'bad JSON' logger, so they will always occur at the same time, due to the block scope.