My express server handle a post request which receives a body containing the next JSON object:
"QnsAns": {
}
How can I validate that object QnsAns HAS nested object? It should look like:
"QnsAns": {
"Q1": "A1",
"Q2": "A2",
"Q3": "A3",
"Q4": "A4",
"Q5": "A5"
}
Using express validator, I tried using '*' wildcard, optional(), exist() but all result with no success
Thanks!
To check if "QnsAns" constains "Q1" you can use hasOwnProperty
console.log(QnsAns.hasOwnProperty('Q1'));
To check type of Q1, you can use typeOf
console.log(typeof(Q1);
If you have to use this multiple times, try out Joi Validations
The question is not very clear. Is this object in JSON format? Can you please post some more details to it so that it will help.
Now, as a simple solution you can do something like this, assuming the object is stored in a variable data.
function checkIfNestedObjectIsEmpty() {
let data = <Your Object>
return (Object.entries(data[Object.keys(data)]).length === 0)
}
Related
{
acknowledged: true,
insertedId: new ObjectId("612d9d08db9c20f031033478")
}
This was the JSON format I got while I added a file and some other things to MongoDB and I want to get this id separately to save the file to another folder.
Can anyone please explain this?
I believe this question was answered by Vikas in this thread How to get value from specific key in NodeJS JSON [duplicate]
Edited The Answer. Now Its working for above object in question
You can use following function to access the keys of JSON. I have
returned 'mm' key specifically.
function jsonParser(stringValue) {
var string = JSON.stringify(stringValue);
var objectValue = JSON.parse(string);
return objectValue['mm'];
}
if this is a JSON String, at first of all you have to parse it to object liertal, then you can access the specified property you mentioned, so you can do like the following:
function parseJsonString(jsonString) {
// first parse it to object
var obj = JSON.parse(jsonString);
// now access your object property/key
var id = obj.insertedId;
}
If your doing it on mongodb shell or Robo3T then, the line of code would be:
db.collection_name.find({},{insertedId:1})
This is related to projection. 1 represents you want to display it as your output.
In your case as you want only the value of your object id to get displayed, you have to use .valueOf() ; that is ObjectId().valueOf().
-> insertedId: new ObjectId("612d9d08db9c20f031033478")
-> ObjectId("612d9d08db9c20f031033478").valueOf()
->
-> 612d9d08db9c20f031033478
Your can refer this : https://docs.mongodb.com/manual/reference/method/ObjectId.valueOf/ site for your reference.
So you can use this .valueOf() in your code and get the id saved in the document
My JSON is:
body =
{
"session_id":"45470003-6b84-4a2b-bf35-e850d1e2df8b",
"message":"Thanks for calling service desk, may I know the store number you are calling from?",
"callstatus":"InProgress",
"intent":"",
"responseStatusCode":null,
"responseStatusMsg":null,
"context":"getstorenumber"
}
How to get message value using Node js? Please let me know after testing.
i tried body.message and body['message'] and also body[0]['message']. I am always getting "undefined"
#Chris comment, since the problem is sorted out, Adding the answer to all members for future ref.
From node.js result, body is taken as JSON string, using JSON.parse.body converted to json object.
body =
{
"session_id":"45470003-6b84-4a2b-bf35-e850d1e2df8b",
"message":"Thanks for calling service desk, may I know the store number you are calling from?",
"callstatus":"InProgress",
"intent":"",
"responseStatusCode":null,
"responseStatusMsg":null,
"context":"getstorenumber"
}
JSON.parse.body
console.log(body.message);
As per the API documentation for Cloudant: Show function can be used to render a document in a different format or extract only some information from a larger document. Same is the case for a list function, the only difference is that it applies on a set of documents. I created a design document with a show function as follows:
{ "shows": { "showDemo":"function(doc,req){return {'body': doc, 'headers':{'Content-Type':'application/json'}}}" } }
When I use this function, _design/showFunc/_show/showDemo/doc1, I get the following error:
{ "error": "unknown_error", "reason": "badarg", "ref": 1793182837 }
I have observed the same error when the show function returns an array. However, no error is given when HTML,Text, XML is returned. Can we say that list/show functions can only return data in a format other than JSON? This example shows the "Accept" header for req object request Object.
What's happening here is that the show function needs to return a response object. From the docs (see http://docs.couchdb.org/en/2.1.0/json-structure.html#response-object) the body field needs to be a string, so you can return whatever you like but it needs to be stringified or otherwise turned into a format that can be sent as HTTP.
If you want to send JSON then doing JSON.Stringify(doc) as the value for body should do what you expect.
I try to transform flat JSON data from an Event Hub into a DocumentDB. The target structure should look like:
{
"id" : 1
"field_1" : "value_1",
"details" : {
"detail_field_1":"abc",
"detail_field_2":"def"
}
}
Created from source:
{
"id":1,
"field_1" : "value_1",
"detail_field_1":"abc",
"detail_field_2":"def"
}
I checked the documentation of Azure Stream Analytics but there ist no clear description how to create a proper Query.
Who one can help me?
You can leverage the new JavaScript UDF feature to write nested JSON objects to output.
Register a user-defined function, "UDF.getDetails()" as below:
function main(obj) {
//get details object from input payload
var details_obj = {};
details_obj.detail_field_1 = obj.detail_field_1;
details_obj.detail_field_2 = obj.detail_field_2;
return JSON.stringify(details_obj);
}
Then call the UDF in your query to get a string of the nested JSON object.
SELECT
id,
field_1,
UDF.getDetails(input) As details
INTO output
FROM input
Using JavaScript UDF feature, you can return complex JSON.
Example write function.
function main(obj) {
//get details object from input payload
var details_obj = {};
details_obj.detail_field_1 = obj.detail_field_1;
details_obj.detail_field_2 = obj.detail_field_2;
return details_obj;
}
You should not use JSON.stringify since it will make it a string instead of JSON object.
Use it like.
SELECT id, field_1, UDF.getDetails(input) As details
INTO output
FROM input
I have been searching for hours, but I cannot find anything about this.
Situation:
Backend, existing of NodeJS + Express + Mongoose (+ MongoDB ofcourse).
Frontend retrieves object from the Backend.
Frontend makes some changes (adds/updates/removes some attributes).
Now I use mongoose: PersonModel.findByIdAndUpdate(id, updatedPersonObject);
Result: added properties are added. Updated properties are updated. Removed properties... are still there!
Now I've been searching for an elegant way to solve this, but the best I could come up with is something like:
var properties = Object.keys(PersonModel.schema.paths);
for (var i = 0, len = properties.length; i < len; i++) {
// explicitly remove values that are not in the update
var property = properties[i];
if (typeof(updatedPersonObject[property]) === 'undefined') {
// Mongoose does not like it if I remove the _id property
if (property !== '_id') {
oldPersonDocument[property] = undefined;
}
}
}
oldPersonDocument.save(function() {
PersonModel.findByIdAndUpdate(id, updatedPersonObject);
});
(I did not even include trivial code to fetch the old document).
I have to write this for every Object I want to update. I find it hard to believe that this is the best way to handle this. Any suggestions anyone?
Edit:
Another workaround I found: to unset a value in MongoDB you have to set it to undefined.
If I set this value in the frontend, it is lost in the REST-call. So I set it to null in the frontend, and then in the backend I convert all null-values to undefined.
Still ugly though. There must be a better way.
You could use replaceOne() if you want to know how many documents matched your filter condition and how many were changed (I believe it only changes one document, so this may not be useful to know). Docs: https://mongoosejs.com/docs/api/model.html#model_Model.replaceOne
Or you could use findOneAndReplace if you want to see the document. I don't know if it is the old doc or the new doc that is passed to the callback; the docs say Finds a matching document, replaces it with the provided doc, and passes the returned doc to the callback., but you could test that on your own. Docs: https://mongoosejs.com/docs/api.html#model_Model.findOneAndReplace
So, instead of:
PersonModel.findByIdAndUpdate(id, updatedPersonObject);, you could do:
PersonModel.replaceOne({ _id: id }, updatedPersonObject);
As long as you have all the properties you want on the object you will use to replace the old doc, you should be good to go.
Also really struggling with this but I don't think your solution is too bad. Our setup is frontend -> update function backend -> sanitize users input -> save in db. For the sanitization part, we use a helper function where we integrate your approach.
private static patchModel(dbDocToUpdate: IModel, dataFromUser: Record<string, any>): IModel {
const sanitized = {};
const properties = Object.keys(PersonModel.schema.paths);
for (const key of properties) {
if (key in dbDocToUpdate) {
sanitized[key] = data[key];
}
}
Object.assign(dbDocToUpdate, sanitized);
return dbDocToUpdate;
}
That works smoothly and sets the values to undefined. Hence, they get removed from the document in the db.
The only problem that remains for us is that we wanted to allow partial updates. With that solution that's not possible and you always have to send everything to the backend.
EDIT
Another workaround we found is setting the property to an empty string in the frontend. Mongo then also removes the property in the database