I receive these huge Strings via WebSocket:
[
"BTC-31DEC21-100000-P",
"{\"data\":{\"bids\":{\"0.01\":{\"price\":0.01,\"volume\":66.2,\"exchange\":\"DER\"},\"5.0E-4\":{\"price\":5.0E-4,\"volume\":1.1,\"exchange\":\"DER\"},\"0.637\":{\"price\":0.637,\"volume\":8.4,\"exchange\":\"DER\"}},\"asks\":{\"0.664\":{\"price\":0.664,\"volume\":8.4,\"exchange\":\"DER\"}}},\"isMasterFrame\":true}"
]
or
[
"BTC-31DEC21-36000-C",
"{\"data\":[{\"price\":0.422,\"volume\":8.4,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.423,\"volume\":0.0,\"exchange\":\"DER\",\"side\":\"ASKS\"}],\"isMasterFrame\":false}"
]
or
[
"BTC-31DEC21-60000-P",
"{\"data\":[{\"price\":0.105,\"volume\":0.0,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.1055,\"volume\":28.7,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.106,\"volume\":7.6,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.1065,\"volume\":43.0,\"exchange\":\"DER\",\"side\":\"ASKS\"}],\"isMasterFrame\":false}"
]
I want to check for isMasterFrame
let payload = JSON.parse(messageString[1]);
if (payload.hasOwnProperty("isMasterFrame")) {
for (let i = 0; i < payload.pairs.length; i++) {
let currentPair = payload.data[i]
currentPair = currentPair.replace(/\0/g, ''); //Remove null chars
if (currentPair.toUpperCase() != 'KILL') {
props.onAddAvailablePair(currentPair);
}
}
} else {
// print some output with payload which holds "isMasterFrame":false
}
When I run the code I get error:
TypeError: Cannot read properties of undefined (reading 'length')
Data from one inner pair: {\"price\":0.423,\"volume\":0.0,\"exchange\":\"DER\",\"side\":\"ASKS\"} should be split and inserted into the loop one by one
Do you know how I can fix this issue?
You don't have property pairs inside payload object, so you can not access its length.
You should iterate over data property. Since data property is also object, you can use Object.keys() function and iterate over its sub-properties.
let payload = JSON.parse(messageString[1]);
if (payload.hasOwnProperty("isMasterFrame")) {
for (let i = 0; i < Object.keys(payload.data).length; i++) {
let current_property= payload.data[Object.keys(payload.data)[i]];
console.log(current_property);
...
Your data has different structure when isMasterFrame is different. You have Object of bids and asks in data when isMasterFrame is true while it is an array when isMasterFrame is false.
const data1 = [
"BTC-31DEC21-100000-P",
"{\"data\":{\"bids\":{\"0.01\":{\"price\":0.01,\"volume\":66.2,\"exchange\":\"DER\"},\"5.0E-4\":{\"price\":5.0E-4,\"volume\":1.1,\"exchange\":\"DER\"},\"0.637\":{\"price\":0.637,\"volume\":8.4,\"exchange\":\"DER\"}},\"asks\":{\"0.664\":{\"price\":0.664,\"volume\":8.4,\"exchange\":\"DER\"}}},\"isMasterFrame\":true}"
],
data2 = [
"BTC-31DEC21-36000-C",
"{\"data\":[{\"price\":0.422,\"volume\":8.4,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.423,\"volume\":0.0,\"exchange\":\"DER\",\"side\":\"ASKS\"}],\"isMasterFrame\":false}"
]
data3 = [
"BTC-31DEC21-60000-P",
"{\"data\":[{\"price\":0.105,\"volume\":0.0,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.1055,\"volume\":28.7,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.106,\"volume\":7.6,\"exchange\":\"DER\",\"side\":\"ASKS\"},{\"price\":0.1065,\"volume\":43.0,\"exchange\":\"DER\",\"side\":\"ASKS\"}],\"isMasterFrame\":false}"
];
const formatData = (data) => {
return data.reduce((r, o) => {
Object.entries(o).forEach(([k,v]) => {
r[k] ??= [];
r[k].push(v);
});
return r;
}, {})
}
[data1, data2, data3].forEach(data => {
const o = JSON.parse(data[1]);
if(o.isMasterFrame) {
const result = formatData(Object.values(o.data.bids));
console.log(result);
} else {
const result = formatData(o.data);
console.log(result);
}
});
You can run the code snippet below to see it in operation. I have also attached a screenshot of a console showing the output of values.
// THIS IS AN ARRAY CONTAINING A JSON
var messageString = [
"BTC-31DEC21-100000-P",
"{\"data\":{\"bids\":{\"0.01\":{\"price\":0.01,\"volume\":66.2,\"exchange\":\"DER\"},\"5.0E-4\":{\"price\":5.0E-4,\"volume\":1.1,\"exchange\":\"DER\"},\"0.637\":{\"price\":0.637,\"volume\":8.4,\"exchange\":\"DER\"}},\"asks\":{\"0.664\":{\"price\":0.664,\"volume\":8.4,\"exchange\":\"DER\"}}},\"isMasterFrame\":true}"
];
// THE JSON IS AT INDEX '1' OF THE ARRAY SO WE PARSE IT
let payload = JSON.parse(messageString[1]);
// YOU CAN SEE THE PARSED JSON IN CONSOLE
console.log(payload.data);
// SINCE isMasterFrame IS EITHER TRUE OR FALSE, WE CAN TEST FOR IT WITHOUT USING hasOwnProperty
// IF isMasterFrame IS UNDEFINED OR NOT IN THE JSON, THE ELSE BLOCK WILL EXECUTE AND NOT BREAK THE CODE
if (payload.isMasterFrame) {
console.log("1 payload.isMasterFrame: " + payload.isMasterFrame);
// SINCE IT IS A JSON, WE HAVE TO LOOP THROUGH THE FIRST PART THIS WAY
for (var key in payload.data) {
if (payload.data.hasOwnProperty(key)) {
console.log("key base: " + key + " -> " + payload.data[key]);
// SINCE THE VALUE IS ALSO A JSON OF VALUES, WE LOOP THROUGH AGAIN
for (var key_inner1 in payload.data[key]) {
if (payload.data[key].hasOwnProperty(key_inner1)) {
console.log("key inner1: " + key_inner1 + " -> " + payload.data[key][key_inner1]);
// GETTING THE CURRENT PAIR
let currentPair = payload.data[key][key_inner1];
console.log("CURRENT PAIR");
console.log(currentPair);
/*
currentPair = currentPair.replace(/\0/g, ''); //Remove null chars
if (currentPair.toUpperCase() != 'KILL') {
props.onAddAvailablePair(currentPair);
}
*/
// SINCE THE VALUE IS ALSO A JSON OF VALUES, WE LOOP THROUGH AGAIN TO GET THE REAL VALUES
for (var key_inner2 in payload.data[key][key_inner1]) {
if (payload.data[key][key_inner1].hasOwnProperty(key_inner2)) {
// NOW WE CAN DO WHAT WE NEED TO WITH THE ACTUAL VALUES
console.log("key inner2: " + key_inner2 + " -> " + payload.data[key][key_inner1][key_inner2]);
}
}
}
}
}
}
} else {
console.log("2 payload.isMasterFrame: " + payload.isMasterFrame);
}