SocketIO cannot access JSON properties from ON - json

I don't know if I'm going crazy here but I'm doing something very basic that would usually be trivial, but I've been stuck on it for awhile now.
I'm receiving a message from a client like so:
socket.on('request_username', function(messageFromClient) {
if(messageFromClient == undefined) {
Logger.logError("messageFromClient was undefined in socket_api.js");
return;
}
// Parse the message into Json, might not be needed.
// Logs: "{\"username\":\"test\"}"
console.log(messageFromClient);
try {
messageFromClient = JSON.parse(messageFromClient);
//Logs: {"username":"test"}
console.log(messageFromClient);
} catch(err) {
console.log("Error parsing json from request_username. Mesage is %s", err);
return;
}
// All undefined.
console.log(messageFromClient['"username"']);
console.log(messageFromClient["username"]);
console.log(messageFromClient['username']);
// msg == undefined incase the parse failed.
if(messageFromClient == undefined || messageFromClient.username == undefined) {
Logger.logError("messageFromClient.username was undefined in socket_api.js");
return;
}
var usernameRequested = messageFromClient.username;
Now I'm getting this in the logs
"{\"username\":\"test\"}"
{"username":"test"}
Log Error: messageFromClient.username was undefined in socket_api.js
I've no idea what I'm doing wrong..

With socket.io, it automatically serializes Javascript data to/from JSON. You do not have to do that and if you attempt to, you can mess things up.
In socket.io, you can send like this:
var data = {username: "test"};
socket.emit('request_username', data);
Then, on the receiving side, you would have:
socket.on('request_username', function(data) {
console.log(data.username); // will show "test"
});
The serializing to/from JSON is done automatically by the socket.io library (one of its many useful features).
To debug your particular situation further, we will need to know exactly what the very first console.log(messageFromClient) shows right when the message first arrives before you've done anything to it?
You show a bunch of log info, but it's not entirely clear which debug line corresponds with which line of code. If that very first console.log shows:
"{\"username\":\"test\"}"
then your message is apparently still JSON which is probably because it was doubly JSON encoded which is an error on the sending side. This should be fixed on the sending side rather than trying to double parse it.
Also, when discussing this problem please be aware that JSON is a string format. A Javascript object is something you can directly access properties on in Javascript code. It appears you are sometimes calling them both JSON which is confusing for all. You convert a Javascript object to JSON with var jsonStr = JSON.stringify(obj) and you convert JSON to a Javascript object with var obj = JSON.parse(someJSON).
var obj = {username: test}; // Javascript object
var jsonStr = JSON.stringify(obj); // produces a JSON string
var obj2 = JSON.parse(jsonStr); // parses JSON string back to a Javascript object

Related

typescript - load json from url and get access to array of json objects

I just can't find a working solution and implement in my format.
There is a JSON file which is returned to me by URL. Its format is:
{"success":true,
"data":[
{
"loadTimestamp":"2022-07-20T15:12:35.097Z",
"seqNum":"9480969",
"price":"45.7",
"quantity":"0.2",
"makerClientOrderId":"1658329838469",
"takerClientOrderId":"1658329934701"
},
{
"loadTimestamp":"2022-07-20T14:49:11.446Z",
"seqNum":"9480410",
"price":"46",
"quantity":"0.1",
"makerClientOrderId":"1658328403394",
"takerClientOrderId":"0"
}]
}
Due to the fact that it is returned via the URL, it is not possible to directly use the object, for example:
myobj['data']['price']
I have either a string of data that I can convert using JSON.parse() or an object right away.
But for some reason I can't use it directly.
As far as I understand, this is a JSON file inside which is an array of JSON data.
My goal is to display all the data from the array, while taking for example 2 values: price, quantity
How can I access the values that I want to get?
Ok I find, what I was looking for.
I return result not in json, but in text response.text()
After I did this, I create a new constant called res and put in it JSON.parse(data)
const url = 'https://myurl.com/'+pub_key
const response = await fetch(url)
let data = ''
if (response.ok) { data = await response.text() } else { console.log("Error HTTP: " + response.status) }
const res = JSON.parse(data)
After all this manipulations I can use my data with 2 ways:
console.log(res["data"][0]["price"])
console.log(res.data[0].price)
Or I can make a cocktail from it, by using my favorite blender :)))
if(res.success==true){
for(let item in res.data){
console.log(res.data[item].price,res.data[item].quantity)
}
}

parse json response to typescript class

i know there are multiple similar topics, however trying their solutions doesn't give me expected result.
Input json string
data:"{"message": "{\"type\":\"CONTROL\",\"command\":\"REQUEST_STATUS_ALL\"}"}"
object declaration/parse:
const msg: Message = <Message>JSON.parse(data.data);
output:
{message: "{"type":"CONTROL","command":"REQUEST_STATUS_ALL"}"}
-values are not properly assigned, but instead in a text form.
the same object looks like this if it's initialized manually(in TS):
MessageĀ {type: "CONTROL", status: undefined, command: "REQUEST_STATUS_ALL", body: undefined}
What is the correct way to parse that json string into the Message object?
Thank you!
It seems the value for message was improperly encoded as a string. Calling JSON.parse a second time on the message property will get the result you want, though you might want to fix the underlying cause of the improperly encoded data instead.
parseMessage(data: string) {
const msgTemp = JSON.parse(data);
msgTemp.message = JSON.parse(msgTemp.message);
return <Message>msgTemp;
}
const msg = parseMessage(data.data);

Unable to access existing fields in JSON object, keep getting undefined

I have a function in AWS Lambda in which I retrieve an unparsed JSON object, I parse it, and then access its values.
if(data.Payload){
var parsedData = JSON.parse(data.Payload)
console.log("PAYLOAD --> " + parsedData);
console.log("GROUPNAME --> " + parseData.groupName);
...
When I log to the console the parsedData variable, it seems like the parsing was successful:
PAYLOAD --> {"groupName":"Hello!","membersCount":1,"searchField":"hello!"}
The issue arises when I try to access the fields in the JSON as I keep getting undefined:
GROUPNAME --> undefined
NOTE:
If I copy and paste the JSON object
{"groupName":"Hello!","membersCount":1,"searchField":"hello!"}
into a variable on the Chrome debugging console
var parsedData = {"groupName":"Hello!","membersCount":1,"searchField":"hello!"}
I am able to access the properties of the object as I am trying to do in the AWS Lambda function.
parsedData.groupName prints "Hello!"
Edit - temporary solution
The parsedData variable contains a String with a JSON, so the JSON object inside the "" I am not quite sure why. The temporary fix was to double parse the variable but that just seems wrong.
if(data.Payload){
var parsedData = JSON.parse(data.Payload);
var doubleParsed = JSON.parse(parsedData);
if(doubleParsed.groupName !== undefined) {
console.log(doubleParsed.groupName);
}
}
If that is a copy paste of your code, in your 2nd console.log you are using parseData NOT parsedData missing a D.
EDIT Just adding as answer what I wrote in comments.
It seems parsedData was not being parsed correctly, for some reason JSON.parse is not working, I think some information about data.Payload is needed to know what it exactly returns.
Yet the next code seems to solve it, but I would honestly need further explanation as why it needs to be done twice:
var parsedData = JSON.parse(JSON.parse(data.Payload));

How can i make a new single json object by extracting particular fields from realtime json data using node.js

I have the following code which publishes the json data in the specified url using mqtt.The initial data is retrieved from http.
var request = require('request');
var JSONStream = require('JSONStream');
var es = require('event-stream');
var mqtt = require('mqtt');
request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
.pipe(JSONStream.parse('rows.*'))
.pipe(es.mapSync(function (data) {
console.info(data);
var client = mqtt.createClient(1883, 'localhost');
client.publish('NewTopic', JSON.stringify(data));
client.end();
return data;
}))
The following is the subscriber code which subscribes the data that is published (in the above code) through mqtt
var mqtt = require('mqtt');
var client = mqtt.createClient();
client.subscribe('NewTopic');
client.on('message', function(topic, message) {
console.info(message);
});
In the above code, I get all json data in the specified url in 'message'.I need to extract 'id' and 'value' from the received data and make it as a single JSON object and need to publish it to mqtt,so that another client can subscribe only the 'id' and 'value' as json data.
To convert a JSON text into an object, you can use the eval() function. eval() invokes the JavaScript compiler. Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure. The text must be wrapped in parens to avoid tripping on an ambiguity in JavaScript's syntax.
var myObject = eval(message);
The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and competent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. But it might not be competent. If the server is not rigorous in its JSON encoding, or if it does not scrupulously validate all of its inputs, then it could deliver invalid JSON text that could be carrying dangerous script. The eval function would execute the script, unleashing its malice.
To defend against this, a JSON parser should be used. A JSON parser will recognize only JSON text, rejecting all scripts. In browsers that provide native JSON support, JSON parsers are also much faster than eval.
var myObject = JSON.parse(message);
And use it as a Object:
myObject.id;
myObject.value;
Create a object with just id and value :
var idAndValueObj = {};
idAndValueObj.id = myObject.id;
idAndValueObj.value = myObject.value;
Convert to JSON string:
var jsonStr = JSON.stringify(idAndValueObj);

WebClient.DownLoadString is adding \" infront of my JSON data elements.How to parse it as normal JSON without \"?

I am trying to access a REST Service in my MVC application.I am calling getJSON method to get the data from a controller which internally calls the REST service which returns data in json format.But I am getting the a lot of "\ in my output of DownLoadString method and my return Json is not returning proper JSON data and hence my client side script is not able to access the JSON properties.
My Script in my view is
$.getJSON("#Url.Action("GetManufacturers", "Home")",function(data){
console.debug("Status is : "+data.Status)
});
My Action method looks like this
public ActionResult GetManufacturers()
{
string restURL ="http://mytestserver/myapi/Manufacturers";
using (var client = new WebClient())
{
var data = client.DownloadString(restURL);
//data variable gets "\" everywhere
return Json(data,JsonRequestBehavior.AllowGet);
}
}
I used visual studio breakpoints in my action method and i am seeing a lot of \"
And i checked what is coming out to my getJSON callback and the JSON tab is empty.
But my response tab has content like this
I belive if there is no \", i would be able to parse it nicely.
I used fiddler to see whether i am getting correct (JSON format) data from my REST service and it seems fine.
Can anyone help me to tackle this ? I would like to return proper JSON from my action method. Sometime i may want to read the json properties in the C# code itself. I saw some example of doing it with DataContractJsonSerializer. But that needs a concrete type to be converted to. I don't want to do that. because other clients would also access my RESTService and how will expect them to write a fake entity for this ?
You need to return the data as is:
public ActionResult GetManufacturers()
{
string restURL ="http://mytestserver/myapi/Manufacturers";
using (var client = new WebClient())
{
var data = client.DownloadString(restURL);
return Content(data, "application/json");
}
}