Why do I get "Uncaught SyntaxError" while parsing JSON string? - javascript

I am currently struggling with a JSON string that I receive from my server application.
This is the JavaScript snippet that receives the JSON string:
var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
connection.onmessage = function (e) {
console.log('Received from server: ', e.data);
var response = JSON.parse(e.data);
if(response.action=="networks") {
console.log('SSID: ', response.ssid);
}
};
I get this response in my browser's console according to my console.log call above:
Received from server: {"action":"networks","ssid":"UPC6288862","rssi":-69,"enc":8}
Ending in the following error:
Uncaught SyntaxError: Unexpected token in JSON at position 60
at JSON.parse (<anonymous>)
at WebSocket.connection.onmessage (WebSocket.js:19)
connection.onmessage#WebSocket.js:19
When I manually put the string, to JSON.parse() like this:
var data = JSON.parse('{"action":"networks","ssid":"UPC Wi-Free","rssi":-42,"enc":255}');
the parsing works and I can access the fields by response.action for example.
But why I get the error? Is e.data not a proper string or do I need to add some quotes or similar to e.data before parsing?
UPDATE:
Here's a screenshot of Chrome's network tab while receiving the JSON string via the WebSocket.js:

Related

API with Google Script Apps

I'm having trouble using Google Apps to interact with a management software called Kissflow.
function fun2() {
var id = "yyy";
var apisecretkey = "xxx";
var url ='https://'+id+'.kissflow.com/api/1/verify';
var options = {
method: 'post',
headers : {"Authorization" : " Basic " + Utilities.base64Encode(id + ":" + apisecretkey)},
payload: {
"grant_type": "client_credentials",
"scope": "basic+user"
},
muteHttpExceptions: true
};
var response = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
}
I would like to run this simple example of the API documentation, the goal is for me to be able to send data to the software through my interactions in a spreadsheet, for example. If you can help me in this I will be very grateful, I am new with API's :)
The following error appears: SyntaxError: unexpected token <in JSON at position 0 (line 30, file "Code") I don't know if I'm using this function correctly.
Kissflow API Documentation
JSON.parse(UrlFetchApp.fetch(url, options).getContentText())
Remove JSON.parse() from above line and output the response on your console using Logger.log() or to your browser log using console.log() and see the result. If there are errors it'll show more user friendly error message.
While I'm not familiar with the API, I suspect the issue is related to this line:
var response = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
You're fetching the response (which is probably JSON), then getting the content text of that response, then trying to parse that text as if it were JSON.
So (solution 1) if you set your response variable equal to
var response = UrlFetchApp.fetch(url, options).getContentText();
and try printing that variable to the console, you may find you have something you can work with.
Alternatively (solution 2), you might try:
var response = JSON.parse(UrlFetchApp.fetch(url, options));
if you'd rather have a JavaScript object to work with instead of a string (and assuming the .fetch method you're calling does indeed provide a JSON-formatted response.)

Node Res.write send multiple objects:

I am trying to send multiple objects in the response as json back to client from one route. It is some kind of middleware, that gets called, and then it calls itself another route inside to get the data and do some data processing. Here is the code:
const axios = require('axios');
var datetime = require('node-datetime');
function MiddlewareRoutes(router) {
var MiddlewareController = require('../controllers/MiddlewareController')
router.route('/Middleware/someotherLink/parametres').get(function(req,res,next) {
console.log(req.params.id, req.params.startTime, req.params.endTime);
url = `http://localhost:hidden/link/..`;
url2 = "http://localhost:port+params..."
axios.get(url) //, {responseType: 'json',}
.then(response => {
var formattedData = formatData(response.data);
[max,min] = getMinMax(formattedData);
res.write("max:",max);
res.write("min:",min);
res.write(formattedData);
res.end();
})
.catch(error => {
console.log(error);
});
})
}
However, I am getting the error:
TypeError: First argument must be a string or Buffer
at write_ (_http_outgoing.js:642:11)
at ServerResponse.write (_http_outgoing.js:617:10)
at axios.get.then.response (C:\Users\U500405\Desktop\Backend\routes\MiddleWare.js:19:13)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
What am I doing wrong? I cannot just send strings, because I have to send objects...
Write is for writing strings to the response body, the parameters accepted are (chunk[, encoding][,callback]), however an object is not a string, and your min/max values are not encodings.
As said before, you could use JSON.stringify to convert an object into a JSON string, however since this is pretty common behaviour Express provides a send method that can do exactly that.
res.write(JSON.stringify({
min,
max,
formattedData
}));
or
res.send({
min,
max,
formattedData
});
res.write(formattedData); Here formatted data is a object . As the error message says, write expects a string or Buffer object, so you must convert it. by doing so : res.write(JSON.stringify(formattedData)) . The node expects the content to not to be a object because it needs string to pass on to the server. The server only understands plain text input as mentioned in Nodejs Docs Nodejs Doc Link for res.write() , and by default the encoding is 'utf-8' . so When sending a object through the server , the server discards it and throws an error of expected buffer chunks or string data.

Node.js Request module returns truncated data

I'm using request on my nodejs server to call an external JSON rest service.
This is a simplified example of my code :
var request = require("request");
request("http://www.sitepoint.com", function(error, response, body) {
var myJson = eval('(' + body+ ')');
});
It works well 90% of the time, but sometime I get this error :
Uncaught Syntax Error: Unexpected Token ILLEGAL
This error never refers to the same char into the received JSON, So in my understanding, the stream sent back by the rest service is truncated and cannot be converted to JSON.
How can I ensure myself that the request is done completly and the data complete ?

Send file via Post using new SDK Firefox Addon

I'm searching to send a zip file to a server using the "Request" class from the new Firefox SDK for addons. This is my code:
var Request = require("sdk/request").Request;
var file = new FileUtils.File(pathToZipFile);
Request({
url: serverURL,
content: file,
onComplete: function (response) {
for (var headerName in response.headers) {
console.log(headerName + " : " + response.headers[headerName]);
}
console.log("Response " + response.text );
}
}).post();
But the error is:
[Exception... "Component returned failure code: 0x80520009 (NS_ERROR_FILE_INVALID_PATH) [nsILocalFile.target]" nsresult: "0x80520009 (NS_ERROR_FILE_INVALID_PATH)" location: "JS frame :: resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/querystring.js :: stringify/< :: line 70" data: no]
I have tried to do some checks and:
The server is on and receives normal GET and POST without files
The zip file is present and the path is right
Do you see any errors?
Thanks a lot
The only way to do it with the Request module is to base a base64 encoded string to the content key. If you don't use this, then you can send data such as a Blob or DOMFile (new File()) instance.
But as we see in the SDK code, the request module sends the data variable on request (if its not a HEAD or GET request).
https://github.com/mozilla/addon-sdk/blob/master/lib/sdk/request.js#L110
The data var is made by running stringify on anything passed to the content key:
https://github.com/mozilla/addon-sdk/blob/master/lib/sdk/request.js#L76
Stringify makes it a string:
https://github.com/mozilla/addon-sdk/blob/f5fab7b242121dccfa4e55ac80489899bb9f2a41/lib/sdk/querystring.js#L30
So you have to send base64 encoded string. Or a binary string. Which sucks.
You can use the sdk/io module to read the file as an ArrayBuffer and then turn that ArrayBuffer into a base64 string or binary string.
This shows how to get a binary string: https://stackoverflow.com/a/16365505/1828637

How to process onmessage event data from websocket

I'm setting up a vert.x project in which I'm sending a snippet of JSON from my Java based server to a javascript client via websocket.
Vert.x server sending the JSON:
vertx.eventBus().send("mongodb-persistor", collectionsQuery, new Handler<Message<JsonObject>>() {
#Override
public void handle(Message<JsonObject> data) {
container.logger().info(data.body().encodePrettily());
ws.write(new Buffer(data.body().toString()));
}
});
The data being sent as outputted on the console:
{
"collections" : [ "AAPL", "AZN", "GOOG", "YHOO", "system.indexes" ],
"status" : "ok"
}
When i receive this on the client:
socket.onmessage = function(event) {
alert("Received data from websocket: " + event.data);
var x = JSON.parse(event.data);
};
I'm getting the error:
Uncaught SyntaxError: Unexpected token o (index):124socket.onmessage
I've read up and it appears as though that's because the JSON has already been parsed. So if I don't parse the JSON, how do i actually access my data? If i just output event.data as string, all I get is the type and size as opposed to the data logged on the console.
EDIT:
I also get the error "Failed to load resource: the server responded with status 404" off the following line /sometimes/, even though event.data is still populated with the correct message size.
alert("Received data from websocket: " + event.data);
Any help is appreciated and I hope this information is self contained enough!
Thanks :)
Turns out in vert.x I shouldn't be returning the JSON wrapped in a Buffer.
Instead I used the method writeTextFrame
vertx.eventBus().send("mongodb-persistor", collectionsQuery, new Handler<Message<JsonObject>>() {
#Override
public void handle(Message<JsonObject> data) {
container.logger().info(data.body().toString());
ws.writeTextFrame(data.body().encode());
}
});

Categories