I have a metadata object in the form
{
filename: "hugearray.json",
author: "amenadiel",
date: "2014-07-11",
introduction: "A huge ass array I want to send to the browser"
}
That hugearray.json is a text file in my folder which contains, as its name implies, an array of potentially infinite elements.
[
[14, 17, 25, 38, 49],
[14, 41, 54, 57, 58],
[29, 33, 39, 53, 59],
...
[03, 14, 18, 34, 37],
[03, 07, 14, 29, 33],
[05, 16, 19, 30, 49]
]
What I want to achieve is to output to the browser an object which is the original object, with the extra key 'content' which is the huge array
{
filename: "hugearray.json",
author: "amenadiel",
date: "2014-07-11",
introduction: "A huge ass array I want to send to the browser",
content: [
[14, 17, 25, 38, 49],
...
[05, 16, 19, 30, 49]
]
}
But since I don't know the array size, I don't want to store the whole thing in memory before outputting, so I thought of using streams. I can stream the array fine with
var readStream = fs.createReadStream("hugearray.json");
readStream.on('open', function () {
readStream.pipe(res);
});
And of course I can send the metadata object to the res with
res.json(metadata);
And I've tried deconstructing metadata, writing each key : value pair and leaving a content key open, then to pipe the file results, then closing the curly braces. It doesn't seem to work:
{
filename: "hugearray.json",
author: "amenadiel",
date: "2014-07-11",
introduction: "A huge ass array I want to send to the browser",
content:
}[
[14, 17, 25, 38, 49],
[14, 41, 54, 57, 58],
[29, 33, 39, 53, 59],
...
[03, 14, 18, 34, 37],
[03, 07, 14, 29, 33],
[05, 16, 19, 30, 49]
]
I guess I need to wrap the stream in my metadata content key instead of trying to output json and stream into the result. ¿Any ideas?
Well, my question went unnoticed but made me win the Tumbleweed badge. It's something.
I kept investigating and I came out with a solution. I was hoping to find a one liner, but this one works too and so far I've been able to output several MBs to the browser without noticeable performance hit in my node process.
This is the method I used
app.get('/node/arraystream', function (req, res) {
var readStream = fs.createReadStream("../../temp/bigarray.json");
var myObject = {
filename: "hugearray.json",
author: "amenadiel",
date: "2014-07-11",
introduction: "A huge ass array I want to send to the browser"
};
readStream.on('open', function () {
console.log('readStream open');
var myObjectstr = JSON.stringify(myObject);
res.write(myObjectstr.substring(0, myObjectstr.length - 1) + ',"content":');
});
readStream.on('error', function (err) {
console.log('readStream error', err);
throw err;
});
readStream.on('close', function () {
console.log('readStream closed');
readStream.destroy();
res.write('}');
res.end();
});
readStream.on('data', function (data) {
console.log('readStream received data', data.length);
var buf = new Buffer(data, 'ascii');
res.write(buf);
});
});
Basically, instead of turning my object into a stream, I turned my array into a buffer.
Related
I am a beginner developer developing with Dart.
There was a problem while working with websockets.
According to the API help, it's obviously JSON.
but data is list of number :(
Why does it work this way?
I'll attach my code and results
please help :(
I'm sorry I'm not good at English, I hope you understand
--------------code--------------------------------
import 'dart:convert';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() async {
/// Create the WebSocket channel
final channel = WebSocketChannel.connect(
Uri.parse('wss://api.upbit.com/websocket/v1'),
);
channel.sink.add(jsonEncode([{"ticket":"test"},{"type":"ticker","codes":["KRW-BTC"]},{"format":"SIMPLE"}])
);
/// Listen for all incoming data
channel.stream.listen(
(data) {
print(data);
},
onError: (error) => print(error),
);
}
ouput
flutter: [123, 34, 116, 121, 34, 58, 34, 116, 105, 99, 107, 101, 114, 34, 44, 34, 99, 100, 34, 58, 34, 75, 82, 87, 45, 66, 84, 67, 34......]
expected
{"mk":"KRW-BTC","tms":1523531768829,"td":"2018-04-12","ttm":"11:16:03","ttms":1523531763000,"tp":7691000.0,"tv":0.00996719,"ab":"BID","pcp":7429000.00000000,"c":"RISE","cp":262000.00000000,"sid":1523531768829000,"st":"SNAPSHOT"}
I am a beginner in programming and at the moment I am performing so SOAP UI tests that rely on groovy scripting. Below I want to assert that everything within the policies DTO contains the correct values:
{
"policies": [
{
"xx": 28,
"xxxxx": 41,
},
{
"xx": 31,
"xxxxxx": 41,
},
{
"xx": 34,
"xxxxx": 41,
},
{
"xx": 37,
"xxxxx": 41,
}
]
}
Now I know how to perform an assert by simply include json.policies.xx[0] and json.policies.xx[1] etc but this seems a little bit long winded. I am assuming there is a better way by iterating through the DTOs within policies to ensure the xxx are correct and the xxxxx is correct. My question is that can somebody provide me an example for me to work with to know how to code this please?
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(response)
assert json.policies.xx[0].toString() = '28'
assert json.policies.xx[1].toString() = '31'
assert json.policies.xx[2].toString() = '34'
assert json.policies.xx[3].toString() = '37'
assert json.policies.xxxxx[0].toString() = '41'
assert json.policies.xxxxx[1].toString() = '41'
assert json.policies.xxxxx[2].toString() = '41'
assert json.policies.xxxxx[3].toString() = '41'
Thank you
You can simplify your assertion to a single line, like:
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(response)
def policies = [[xx: 28, xxxxx: 41], [xx: 31, xxxxx: 41], [xx: 34, xxxxx: 41], [xx: 37, xxxxx: 41]]
assert json.policies == policies
I have a simple loop that extracts a subset of json objects from a larger dataset.
function getData(d) {
var data = {};
for (var i=0; i < d.length; i++){
data[i] = {
'date' : d[i].date,
'light' : Math.round(d[i].details.light/60),
'deep' : Math.round(d[i].details.deep/60),
'awake' : Math.round(d[i].details.awake/60),
'duration': Math.round(d[i].details.duration/60),
'quality': Math.round(d[i].details.quality*10)
};
console.log(data[i]);
};
return data;
}
getData(d);
It generates json results in the form of,
{
date: 20150809,
light: 168,
deep: 206,
awake: 64,
duration: 438,
quality: 100
}, ...
How might I get this into the desired form,
[{
"key":"light",
"date":20150809,
"value":168
},
{
"key":"deep",
"date": 20150809,
"value":206
},
{
"key":"awake",
"date":20150809,
"value":64
},
{
"key":"duration",
"date": 20150809,
"value":438
},
...
{
"key":"quality",
"date":20150809,
"value":6100
}]
My question is, how might I achieve this without iterating over the dataset five times (once for each of the 5 key types)? I assume at least a minimum of one iteration would be required. A jquery solution would be acceptable.
I'm seeking one array containing all the json objects as opposed to an associative array of nested objects.
Thanks
Suppose your data is in a array in this format :
var data = [
{
date: 20150809,
light: 168,
deep: 206,
awake: 64,
duration: 438,
quality: 100
},
{
date: 20153203,
light: 2,
deep: 21,
awake: 21,
duration: 21,
quality: 32
}
...
];
You can try something like this :
var results = [];
data.forEach(function(e) {
for (var key in e) {
if (key !== 'date')
results.push({
key : key,
date : e.date,
value : e[key]
});
}
});
Considering the object
{
date: 20150809,
light: 168,
deep: 206,
awake: 64,
duration: 438,
quality: 100
}
You want to turn each key into a object without looping through every object. I would to the following:
function convertToJson(obj){
var myJson = {};
var myKeys = obj.keys(); // return an array with the keys of the object
myJson.keys = myKeys[1];
myJson.date = myKeys[0]; // your date
myJson.value = obj.light;
... // do the same with the rest of the elements, if you don't want to loop.
return JSON.stringfy(myJson);
}
I'm no javascript guru, so I appreciate any feedback.
I'm currently developing a desktop application with Node-webkit. During that process I need to get some data from a local MySQL-database.
The querying works fine, but I can't figure out how to access the results. I store all of them in an array that is then passed to a function. In the console they look like this:
RowDataPacket {user_id: 101, ActionsPerformed: 20}
RowDataPacket {user_id: 102, ActionsPerformed: 110}
RowDataPacket {user_id: 104, ActionsPerformed: 3}
And here is the query structure:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
for (var i of rows)
ret.push(i);
}
doStuffwithTheResult(ret);
}
How do I retrieve this in the doStuffwithTheResult function? The values are more important, but if I could get the keys as well that would be great.
Turns out they are normal objects and you can access them through user_id.
RowDataPacket is actually the name of the constructor function that creates an object, it would look like this new RowDataPacket(user_id, ...). You can check by accessing its name [0].constructor.name
If the result is an array, you would have to use [0].user_id.
With Object.prototype approach, JSON.parse(JSON.stringify(rows)) returns object, extract values with Object.values()
let result = Object.values(JSON.parse(JSON.stringify(rows)));
Usage:
result.forEach((v) => console.log(v));
I also met the same problem recently, when I use waterline in express project for complex queries ,use the SQL statement to query.
this is my solution: first transform the return value(RowDataPacket object) into string, and then convert this string into the json object.
The following is code :
//select all user (查询全部用户)
find: function(req, res, next){
console.log("i am in user find list");
var sql="select * from tb_user";
req.models.tb_user.query(sql,function(err, results) {
console.log('>> results: ', results );
var string=JSON.stringify(results);
console.log('>> string: ', string );
var json = JSON.parse(string);
console.log('>> json: ', json);
console.log('>> user.name: ', json[0].name);
req.list = json;
next();
});
}
The following is console:
>> results: [ RowDataPacket {
user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
updatedAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
ID: 3,
phone: 2147483647 } ]
>> string: [{"user_id":"2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5","name":"wuwanyu","psw":"123","school":"Northeastern university","major":"Communication engineering","points":"10","datems":"1450514
441486","createdAt":"2015-12-19T08:42:31.000Z","updatedAt":"2015-12-19T08:42:31.000Z","ID":3,"phone":2147483647}]
>> json: [ { user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: '2015-12-19T08:42:31.000Z',
updatedAt: '2015-12-19T08:42:31.000Z',
ID: 3,
phone: 2147483647 } ]
>> user.name: wuwanyu
Hi try this 100% works:
results=JSON.parse(JSON.stringify(results))
doStuffwithTheResult(results);
You can copy all enumerable own properties of an object to a new one by Object.assign(target, ...sources):
trivial_object = Object.assign({}, non_trivial_object);
so in your scenario, it should be enough to change
ret.push(i);
to
ret.push(Object.assign({}, i));
you try the code which gives JSON without rowdatapacket:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
ret = JSON.stringify(rows);
}
doStuffwithTheResult(ret);
}
going off of jan's answer of shallow-copying the object, another clean implementation using map function,
High level of what this solution does: iterate through all the rows and copy the rows as valid js objects.
// function will be used on every row returned by the query
const objectifyRawPacket = row => ({...row});
// iterate over all items and convert the raw packet row -> js object
const convertedResponse = results.map(objectifyRawPacket);
We leveraged the array map function: it will go over every item in the array, use the item as input to the function, and insert the output of the function into the array you're assigning.
more specifically on the objectifyRawPacket function: each time it's called its seeing the "{ RawDataPacket }" from the source array. These objects act a lot like normal objects - the "..." (spread) operator copies items from the array after the periods - essentially copying the items into the object it's being called in.
The parens around the spread operator on the function are necessary to implicitly return an object from an arrow function.
Solution
Just do: JSON.stringify(results)
I found an easy way
Object.prototype.parseSqlResult = function () {
return JSON.parse(JSON.stringify(this[0]))
}
At db layer do the parsing as
let users= await util.knex.raw('select * from user')
return users.parseSqlResult()
This will return elements as normal JSON array.
If anybody needs to retrive specific RowDataPacket object from multiple queries, here it is.
Before you start
Important: Ensure you enable multipleStatements in your mysql connection like so:
// Connection to MySQL
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123',
database: 'TEST',
multipleStatements: true
});
Multiple Queries
Let's say we have multiple queries running:
// All Queries are here
const lastCheckedQuery = `
-- Query 1
SELECT * FROM table1
;
-- Query 2
SELECT * FROM table2;
`
;
// Run the query
db.query(lastCheckedQuery, (error, result) => {
if(error) {
// Show error
return res.status(500).send("Unexpected database error");
}
If we console.log(result) you'll get such output:
[
[
RowDataPacket {
id: 1,
ColumnFromTable1: 'a',
}
],
[
RowDataPacket {
id: 1,
ColumnFromTable2: 'b',
}
]
]
Both results show for both tables.
Here is where basic Javascript array's come in place https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
To get data from table1 and column named ColumnFromTable1 we do
result[0][0].ColumnFromTable1 // Notice the double [0]
which gives us result of a.
db.query('select * from login',(err, results, fields)=>{
if(err){
console.log('error in fetching data')
}
var string=JSON.stringify(results);
console.log(string);
var json = JSON.parse(string);
// to get one value here is the option
console.log(json[0].name);
})
conn.query(sql, (err,res,fields) => {
let rawData = res;
let dataNormalized = {...rawData[0]};
})
//Object Destructuring
This worked for me hope it helps you.
I think it is simplest way to copy object.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Simpler way:
.then( resp=> {
let resultFromDb= Object.values(resp)[0]
console.log(resultFromDb)
}
In my example I received an object in response.
When I use Object.values I have the value of the property as a response, however it comes inside an array, using [0] access the first index of this array, now i have the value to use it where I need it.
I had this problem when trying to consume a value returned from a stored procedure.
console.log(result[0]);
would output "[ RowDataPacket { datetime: '2019-11-15 16:37:05' } ]".
I found that
console.log(results[0][0].datetime);
Gave me the value I wanted.
I had a similar problem and the solution was as follows:
const results = pool.query('sql sentence',[params]);
console.log((results[0])[0].name);
How to ACCESS what you get back from the database, this works for me:
async function getPageId(pageSlug){
let sql_update = 'SELECT id FROM pages WHERE pageSlug = ?';
let arrValues = [
pageSlug
];
let result = await mydb.query(sql_update, arrValues);
let r = JSON.parse(JSON.stringify(result));
if(r?.length){
return r[0].id;
}else{
return false;
}
}
I really don't see what is the big deal with this I mean look if a run my sp which is CALL ps_get_roles();.
Yes I get back an ugly ass response from DB and stuff. Which is this one:
[
[
RowDataPacket {
id: 1,
role: 'Admin',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 2,
role: 'Recruiter',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 3,
role: 'Regular',
created_at: '2019-12-19 16:03:46'
}
],
OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 35,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}
]
it is an array that kind of look like this:
rows[0] = [
RowDataPacket {/* them table rows*/ },
RowDataPacket { },
RowDataPacket { }
];
rows[1] = OkPacket {
/* them props */
}
but if I do an http response to index [0] of rows at the client I get:
[
{"id":1,"role":"Admin","created_at":"2019-12-19 16:03:46"},
{"id":2,"role":"Recruiter","created_at":"2019-12-19 16:03:46"},
{"id":3,"role":"Regular","created_at":"2019-12-19 16:03:46"}
]
and I didnt have to do none of yow things
rows[0].map(row => {
return console.log("row: ", {...row});
});
the output gets some like this:
row: { id: 1, role: 'Admin', created_at: '2019-12-19 16:03:46' }
row: { id: 2, role: 'Recruiter', created_at: '2019-12-19 16:03:46' }
row: { id: 3, role: 'Regular', created_at: '2019-12-19 16:03:46' }
So you all is tripping for no reason. Or it also could be the fact that I'm running store procedures instead of regular querys, the response from query and sp is not the same.
I have such JSON array in file
var jsonfromfile = [
[Date.UTC(2004, 1, 3), 19.3],
[Date.UTC(2004, 1, 10), 12.7],
[Date.UTC(2004, 1, 17), 3.6],
[Date.UTC(2004, 1, 24), 19.1],
[Date.UTC(2004, 1, 31), 12.1],
[Date.UTC(2004, 2, 7), 11.3],
[Date.UTC(2004, 2, 28), 9.3],
[Date.UTC(2004, 3, 6), 14.3],
[Date.UTC(2004, 3, 13), 5.8],
[Date.UTC(2004, 3, 20), 8.6],
[Date.UTC(2004, 3, 27), 19.9],
[Date.UTC(2004, 4, 3), 14.2],
[Date.UTC(2004, 4, 10), 12.8],
[Date.UTC(2004, 4, 17), 10.6],
[Date.UTC(2004, 4, 24), 8.4],
[Date.UTC(2004, 5, 1), 19.8],
[Date.UTC(2004, 5, 8), 13.8]
];
Which i was using as dummy data making first steps with this charts http://www.highcharts.com/products/highstock.
Now i want to use dynamic data with that charts, so i have controller which returning Key-Value data
public virtual JsonResult GetData(int type)
{
Dictionary<string, decimal> data = getData(type);
return Json(data.ToArray(), JsonRequestBehavior.AllowGet);
}
and i calling that controller with jquery ajax.
var jsonFirstTry = {
data: []
};
$.ajax({
url: actionUrl,
dataType: 'json',
cache: false,
data: { type: type },
success: function (items) {
var jsonSecondTry = "[";
$.each(items, function (itemNo, item) {
jsonFirstTry.data.push(item.Key, item.Value);
jsonSecondTry += "[" + item.Key + "," + item.Value + "],";
})
jsonSecondTry = jsonSecondTry.substring(0, jsonSecondTry.length-1);
jsonSecondTry += "];";
//...
}
});
I was trying reproduce the data like in js file (jsonfromfile) jsonFirstTry and jsonSecondTry but couldn't do the data exactly like in js file
Here is how the data loaded from js file looking in debug like that:
Here is how data looking from my first try
Here is second try data(but it is just string so it is not valid data for chart....)
So i need to generate the same jason like in first image, any thoughts how can i do that?
Your initial example ( var jsonfromfile = [... ) is not JSON. It is an array of arrays (in JavaScript), using JavaScript's array literal syntax.
JSON is a string representing a serialized data structure, using a subset of the JavaScript object literal syntax. JSON cannot have method calls or method definitions.
Thus, attempting to provide, in JSON format, what you used as sample data will not work. You need to provide real JSON and manipulate it as needed (calling Date.UTC() on portions of it) when received.