NodeJS gives MongoDB data with missing values and an unexpected $db field - json

I have a simple NodeJS app which is running a http server that is collecting data from a MongoDB instance and presenting the result as JSON:
db.collection(collectionName).findOne({ '_id': id }, function (err, result) {
if (err) {
reportError(err, res);
return;
} else {
outPut(result, res);
}
});
In the outPut function I'm calling JSON.stringify() on the 'result' variable and writing it in the response.
However much of the data is missing, and an empty $db object is included from somewhere. Here is a subset of the data:
"Kommun":1292,
"Lansdel":28,
"Delyta":[
{
"$id":"2",
"$db":""
},
{
"$ref":"691"
},
{
"$ref":"247"
}
Looking at the record using Studio 3T it seems that all the data I expect has been saved.
Why am I not getting all my data in the JSON object? Where is the $db coming from? What is it?

My guess is that you are using DBRefs. In order to include the referenced data from different collections, you must query those yourself. I cannot show you a code example without some more info on the data schema.

Related

Node-Express MySQL API Outputing JSON Array as String

Trying to setup an Express API server to grab some data for a portfolio site. I have set up the MySQL table with an JSON data type for my 'images' column. 'images' is supposed to have multiple image links for a gallery. However, the server outputs the images array as a string instead of an array of strings.
Javascript Code on the API Server
app.get("/getWorks", (req, res) => {
let sql = "select * from works";
db.query(sql, (err, result) => {
if (err) throw err;
console.log(result);
res.send(result);
});
});
The Results
[
{
"workID": 1,
"title": "example",
"images": "[\"https://SERVER_IP/images/example.png\", \"https://SERVER_IP/images/example.png\"]"
}
]
Workaround
I found out a work around to get the desired output adding this:
result = result.map((row) => ((row.images = JSON.parse(row.images)), row));
[
{
"workID": 1,
"title": "example",
"images": ["https://SERVER_IP/images/example.png", "https://SERVER_IP/images/example.png"]
}
]
How come the query is not outputting the data in a JSON array in the first place even though I specified that particular column to be JSON data type in the table?
I figured it out the problem. I was using the wrong MySQL node package. Need MySQL2 for the json formatting.
npm install mysql2
const mysql = require("mysql2");

NodeJS: How to send entity from mysql to rabbitmq

I'm trying to send an "entity" obtained from MySQL to RabbitMQ.
I'm able to make the connection to the database and return data. Example:
dbConnection.query("SELECT * FROM customer WHERE Id = ?", customerId, (err, rows, fields) => {
...
res.status(200).json(rows)
...
}
After this I am able to watch in Postman the "JSON result", so, I want to send this "JSON result" as an string to RabbitMQ.
I can send to RabbitMq a fake data object with no problem:
const fakeData = {
name: "Elon Musk",
company: "SpaceX",
};
channel.sendToQueue("message-queue", Buffer.from(JSON.stringify(fakeData)));
So, how must I convert the "rows" object returned from MySQL to send it to the queue?
Thank you in advance!
The solution to my problem is as follows:
rows.forEach(function (row) {
channel.sendToQueue("message-queue", Buffer.from(JSON.stringify(row)));
});

Connect Parse with external database?

I am working on project where it is build using traditional technologies like PHP, mysql and it is a web application.
Now we want to build an app for mobile users on platform like Andoid, iOS.
So we are thinking to connect MySql with Parse.com database.
I know parse uses NoSql kind of database for storing objects.
So my question is can we connect parse database to any other SQL database ?
If yes then how we can do that ?
EDIT
#Luca laco I just created a new cloud function like you. which is below.
Parse.Cloud.define("get_parse4j_object",
function(request,response){
// Parameters from client (iOS/Android app)
//var requestedObjectId = request.params.objectId;
// Calling beckend service for getting user information
Parse.Cloud.httpRequest({
method: "GET",
headers: {
'Content-Type': 'application/json'
},
url: "https://api.parse.com/1/parse4j/MLiOgxncUM", /* This could be your url for the proper php module */
//body: { "objectId":requestedObjectId }, /* Here you compose the body request for the http call, passing the php parameters and their values */
success: function(httpResponse) {
/* We expect that the php response is a Json string, using the header('application/json'), so: */
var jsonResponse = JSON.parse(httpResponse.text);
/* sample structure in jsonResponse: { "name":"Joe", "surname":"Banana", "birth_date":"01-02-1999" } */
/* Do any additional stuff you need... */
/* return the result to your iOS/Android client */
return response.success( { "myRequestedUserInfo" : jsonResponse } );
alert(jsonResponse);
},
error: function(httpResponse) {
return response.error({ "msg":"Unable to fetch this user", "code":123456 }); // sample error response
}
});
});
I followed the same way which Luca Laco explained me.
But I am getting error when I am calling function from client JS.
This is my client JS
<script type="text/javascript">
Parse.initialize("APP_ID", "JAVASCRIPT_KEY");
Parse.Cloud.run('get_parse4j_object', {}, {
success: function(result) {
alert(result);
},
error: function(error) {
alert(JSON.stringify(error));
}
});
</script>
In the network tab I can see
POST https://api.parse.com/1/functions/get_parse4j_object 400 (Bad Request)
and error is: {"code":141, "message":"function not found"}
Where I am missing and doing wrong ?
If you mean something like a common mysql connector, then the response is no, you can't. At now, The only way to make parse and something else in relation, is to query from and to Parse. To be clear:
If you want to get a value from Parse, that is stored in mysql, you have to use a http request to a specific php module stored on your php website ( and implemented by you ) that expect some paramenter, and return the result in a specific way, normally in json format, using also the http header application/json.
If you want to get a value from php, that is stored on the parse db, you can run a REST call from php following the spec on the parse website ( https://parse.com/docs/rest/guide/ ), or simply using the php sdk ( https://github.com/ParsePlatform/parse-php-sdk ). Take a look also to the Parse Webhooks.
From what i understood, you already have a working web service, so doing this, you would just proxy the resources stored on your server on mysql to your clients through Parse. In other words you should create a Parse Cloud function for each type of information you want to retrieve on the clients using the Parse SDK (for iOS or Android) and another Parse Colud function for each action you perform on your devices and you want to save on your mysql db, always through Parse system.
My personal opinion, is to stay on Mysql, especially because on Parse we still have a lot of limitation on the queries ( no group by, no distinct, query timeout, etc. ), while seems to be a really good service for the push notification. Anyway all this depends by the complexity of your software and as i said, is just my opinion.
[Edit]
Here an example:
In Parse cloud code, let's make a cloud function called 'get_user_info'
Parse.Cloud.define("get_user_info",
function(request,response){
// Parameters from client (iOS/Android app)
var requestedUserId = request.params.user_id;
// Calling beckend service for getting user information
Parse.Cloud.httpRequest({
method: "POST",
url: "https://www.yourPhpWebsite.com/getUser.php", /* This could be your url for the proper php module */
body: { "php_param_user_id":requestedUserId }, /* Here you compose the body request for the http call, passing the php parameters and their values */
success: function(httpResponse) {
/* We expect that the php response is a Json string, using the header('application/json'), so: */
var jsonResponse = JSON.parse(httpResponse.text);
/* sample structure in jsonResponse: { "name":"Joe", "surname":"Banana", "birth_date":"01-02-1999" } */
/* Do any additional stuff you need... */
/* return the result to your iOS/Android client */
return response.success( { "myRequestedUserInfo" : jsonResponse } );
},
error: function(httpResponse) {
return response.error({ "msg":"Unable to fetch this user", "code":123456 }); // sample error response
}
});
});
The sample 'getUser.php' module could be
<?php
$expectedUserId = $_POST['php_param_user_id'];
// query your MySql db using passed user id
$query = "SELECT name,surname,birth_date FROM MyUserTable Where id = ".$expectedUserId;
// perform your query (the above one is just an example, would be better to use PDO and any other check, just to avoid SQL Injection)
// ...
// ..
// .
$resultQuery = row[0];
// sample json structure
$jsonResponseToParse = '{ "name":'.resultQuery["name"].', "surname":'.resultQuery["surname"].', "birth_date":'.resultQuery["birth_date"].' }';
header('application/json');
echo jsonResponseToParse;
exit();
?>
Hope it helps

node.js read file in, parse to JSON and output

I'm very new to anything much code related, but I'm on a slow and sometimes painful learning curve.
I have a file containing some json which I read into node.js parse and push to a web socket. The script works fine, but I only ever get one json object returned.
devices.json: (Complete file) Not every element has the same data contents, and there is any number of element objects within a data source.
{
"element":"SENS01",
"data":{
"type":"SEN",
"descr":"T100"
},
"element":"SENS02",
"data":{
"type":"SEN",
"descr":"T088",
"uid":"X1A1AA",
"check_on":"2014/06/29"
},
"element":"SENS03",
"data":{
"type":"SEN",
"descr":"T000:",
"uid":"X1A1AB",
"check_on":"2014/06/29"
},
"element":"LED1",
"data":{
"type":"LED",
"state":"0"
}
}
The code which does the stuff is;
server.js:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs');
// creating the server ( localhost:8000 )
app.listen(8000);
// Server started - load page.
function handler(req, res) {
fs.readFile('/var/www/html/dashboard.html', function (err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading web page');
}
res.writeHead(200);
res.end(data);
});
}
// creating a new websocket.
io.sockets.on('connection', function (socket) {
console.log();
// 1st READ of json state file.
fs.readFile('devices.json', 'utf8', function (err, data) {
if (err) throw err;
// Parse/check its valid json.
var dump = JSON.parse(data);
socket.volatile.emit('MAP.room1', dump);
});
});
When I connect to the socket the following is sent (as logged from the server console)
debug - websocket writing 5:::{"name":"MAP.room1","args":[{"element":"LED1","data":{"type":"LED","state":"0"}}]}
I never get any of the other objects, only this one. I've had a look round the net about how to iterate over objects, but it was all largely meaningless to me :(
What I am trying to achieve is when you connect to the web socket every object from the devices.json file is pushed out 1 object at a time. So once this is working I would expect to see;
debug - websocket writing 5:::{"name":"MAP.room1","args":[{"element":"LED1","data":{"type":"LED","state":"0"}}]}
debug - websocket writing 5:::{"name":"MAP.room1","args":[{"element":"SENS03","data":{"type":"SEN","descr":"T000:","uid":"X1A1AB","check_on":"2014/06/29"}}]} etc...
If I put a console.log(data) line in my server.js then I see the entire file as expected. Its only once its been parsed am I left with the 1 entry.
Can anyone please explain what's going on, and how I can best overcome this. It needs to be in a really simple way ideally using my own code/dataset as examples so I can understand 'what this means for me' A lot of the web examples and stuff I read tend to use different examples which just confuses me. I know the basics of declaring variables etc, and have an extremely limited experience with Ruby with a simple script to parse some push data received from an API but that's about it.
If you need any more context etc then please let me know, otherwise any help gratefully received.
I think your problem is that you're using the same keys in your JSON. When the parser reads in that JSON, it continuously overwrites previous values of element and data and since those are the only unique key names, those are the only two values you see.
If you modified your JSON so that the same key names are not used on the same "level," then you would see all of the data you are expecting. Here's an example that makes it easy to iterate through each element:
[
{
"element":"SENS01",
"data":{
"type":"SEN",
"descr":"T100"
}
},
{
"element":"SENS02",
"data":{
"type":"SEN",
"descr":"T088",
"uid":"X1A1AA",
"check_on":"2014/06/29"
}
},
{
"element":"SENS03",
"data":{
"type":"SEN",
"descr":"T000:",
"uid":"X1A1AB",
"check_on":"2014/06/29"
}
},
{
"element":"LED1",
"data":{
"type":"LED",
"state":"0"
}
}
]
Or if you can guarantee that the element values are always unique, then perhaps you could also do this:
{
"SENS01":{
"type":"SEN",
"descr":"T100"
},
"SENS02":{
"type":"SEN",
"descr":"T088",
"uid":"X1A1AA",
"check_on":"2014/06/29"
},
"SENS03":{
"type":"SEN",
"descr":"T000:",
"uid":"X1A1AB",
"check_on":"2014/06/29"
},
"LED1":{
"type":"LED",
"state":"0"
}
}
Ok so I found out my data was actually JS objects represented as below in a flat format with every object seperated with a linefeed.
{"SENS01":{"type":"SEN","descr":"T100"}
{"element":"LED1","data":{"type":"LED","state":"0"}
Using linereader (from npm) I was able to read the file in by doing;
lineReader.eachLine('simple.txt', function(line) {
var dump = JSON.parse(line);
socket.emit('MAP.room1', dump);
});
That then output the required data from the web socket.

Nodejs write json to a file

I just started learning nodejs. I am currently working with sockets and made chat program.
I want to save entire chat to a json file. Currently my code is this :
socket.on('chat', function (data) {
message = {user : data.message.user, message : data.message.message};
chat_room.sockets.emit('chat', {message: message});
jsonString = JSON.stringify(message);
fs.appendFile("public/chat.json", jsonString, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
});
This is currently working perfect, but the json which is written in file is wrong.
This gave me a wrong json
{"user":"niraj","message":"hw r u?"}{"user":"ntechi","message":"hello"}{"user":"ntechi","message":"hw r u?"}
The above code is called when message is triggered. I want json in this format
{"user":"awd","message":"hw r u?","user":"ntechi","message":"hello","user":"ntechi","message":"hw r u?"}
Can anyone help me in this? Thanks in advance
The first set of wrong JSON is created because you are appending a piece of JSON to a file each time you get a message.
The second set of JSON is also wrong - each property name has to be unique.
Presumably you want something like:
[
{"user":"niraj","message":"hw r u?"},
{"user":"ntechi","message":"hello"},
{"user":"ntechi","message":"hw r u?"}
]
In which case the logic you need to use is:
Read data from file
Parse data as JSON and assign to a variable
In the event of an error, assign an empty array to that variable
push the message object onto the end of the array
stringify the array
Overwrite the file with the new string