0

A Stitch function returns value types for each non-string field. I believe this is because functions return data in MongoDB Extended JSON.

The Mongo Shell, on the other hand, returns standard JSON, and no value types.

How do I suppress value types returned by a MongoDB function? Is it possible to convert EJSON back to JSON?

For a date field, for example, the Mongo Shell returns:

"dob" : ISODate("1995-01-11T00:00:00.000-07:00")

The same query in a Stitch function returns:

"dob": {
  "$date": {
    "$numberLong": "232182000000"
  }

My Stitch function looks like this:

exports = function(){
    const collection = context.services.get("mongodb-atlas").db("mydb").collection("mycollection");
    const doc = collection.find().toArray();
  return doc;
};

Is there a helper function that can strip out the value types? Something like...

exports = function(){
    const collection = context.services.get("mongodb-atlas").db("mydb").collection("mycollection");
    const doc = collection.find().toArray();
    const noValueTypes = doc.stripValueTypes()
  return noValueTypes;
};
It'sNotMe
  • 1,184
  • 1
  • 9
  • 29
  • 1
    Hi, I'd like to try to help but I need something clarified if that's alright. When you say "The same query in a Stitch function returns..." do you mean from the Stitch Function Editor UI? Are you calling the Function from a client SDK or another Function, or just with the Run button on the Function Editor? – Chris Bush Mar 22 '19 at 20:21
  • Good question. Yes, I'm running the query in 1) the Mongo Shell and 2) the Function Editor in Stitch. The functions are equivalent, but the syntax differs because of the context. The function above is exactly as it appears in the Function Editor. The equivalent Shell query is below. It does not return value types. `db.mycollection.find()` – It'sNotMe Mar 22 '19 at 20:29
  • I'm thinking that you are just seeing the way that the Stitch Function console displays the output. The Stitch Function itself doesn't actually return EJSON -- it returns a regular JS object. I don't believe there's a way to change the way the return value is printed by the Function console. You can use console.log() within your function to print stuff out. – Chris Bush Mar 25 '19 at 22:01
  • Another observation is that you are not awaiting the collection.find() call, so `doc` is actually a Promise. Not sure if this is consequential for you, but I feel it's worth pointing out. – Chris Bush Mar 25 '19 at 22:04
  • The Stitch function is used in a webhook to get data for a React app. The API call returns the typed data. I can access the data with dotted notation (e.g. `absenceDate.$date.$numberLong`). As a result, the front-end code gets nasty when formatting is required (e.g. `{moment(parseInt(ex.absenceDate.$date.$numberLong)).format("MM/DD/YYYY")}`. It works, but it's not ideal. Thanks for giving this your attention. – It'sNotMe Mar 26 '19 at 15:44
  • My mistake. I see now that calling a webhook Function from curl indeed gives me an EJSONified result. Thanks for clarifying. Writing an answer now. – Chris Bush Mar 26 '19 at 16:33

1 Answers1

3

When a Function result is passed to the client, it is indeed serialized as EJSON.

Ideally, your client can parse EJSON back into regular JS objects, e.g. with the EJSON library, which is also built into the Stitch SDK.

Of course, if you are using the Stitch SDK, calling the function directly is even better.

Another option is to use the response object to pass JSON, like so:

exports = function(request, response) {
  // ... get data ...
  response.addHeader(
    "Content-Type",
    "application/json"
  );
  response.setBody(JSON.stringify(myData));
};

Note that JSON can't represent some special BSON types, such as object id, so you will want to keep this in mind when deciding what data to return.

Chris Bush
  • 126
  • 5
  • I hadn't seen the [EJSON library](https://www.npmjs.com/package/ejson). Thanks for that. Rather than rely on another package, I think accessing data in its typed format (e.g. `absenceDate.$date.$numberLong`) is best. As you said, calling the function directly is preferred, and [Service Webhooks](https://docs.mongodb.com/stitch/reference/service-webhooks/) allow that. – It'sNotMe Mar 26 '19 at 17:52
  • "Calling the function directly is even better." Calling the function is much simpler than working with webhooks, and the results are not serialized as EJSON. – It'sNotMe Aug 05 '19 at 19:30