How filter & format a json in node.js? - node.js

I want to format a JSON object in my Nodejs server. Delete some fields, rename some fields, and move some fields.
I have many different schemas need to apply to many different JSON, so I hope has a lib that can parse a configuration file and to it.
Maybe a configuration file like this:
DELETE request.logid
DELETE request.data.*.time
MOVE request.data.images data.images
And a JSON before applies an above schema:
{
"request": {
"data": {
"book": {
"name": "Hello World",
"time": 1546269044490
},
"images": [
"a-book.jpg"
]
},
"logid": "a514-afe1f0a2ac02_DCSix"
}
}
After applied:
{
"request": {
"data": {
"book": {
"name": "Hello World"
}
}
},
"data": {
"images": [
"a-book.jpg"
]
}
}
Where is the lib it is?
I know that write a function can do the same thing directly, but the problem is I have too many different schemas and too many different JSON, so I wanna manage them by configuration file rather than a js function.

Yes you could do something like this...
// Note: psuedocode
// Read the configuration file;
const commands = (await readFile('config')).split('\r\n').split(' ');
// your original JSON;
const obj = {...};
// Modify the JSON given the commands
commands.forEach( row=>{
if(row[0]==="DELETE"){
delete obj[row[1]];
}else if(row[0]==="MOVE"){
// use lodash to make your life easier.
_.set(obj,`${row[2]}`,_.get(obj,`${row[1]}`));
delete obj[row[1]];
}else if(...){
...
}
})

Related

Use a wildcard for extract just one type of data

I have a translations structure like the following:
{
"hello": {
"es": "Hola",
"en": "Hello"
},
"hello2": {
"es": "Hola2"
}
}
I want to extract for example the "es" language only. I know I can get all and extract the data with javascript but i want to be if its possible with mongo.
I tried:
let exists = await col.find({}).project({ $regex: { '*.en': 1 } }).toArray()
But dosen't works.

JSONata - JSON to JSON Transformation in Nodejs API

I need to write REST API in Node jS for JSON to JSON transfromation.
There are many library and I sort listed "JSONata"
Please find JSONata simple sample here
The challenge is API receive JSON which has data and map but JSONata require map value without quotes.
{
"data" : {
"title" : "title1",
"description": "description1",
"blog": "This is a blog.",
"date": "11/4/2013"
},
"map" : {
"name": "title",
"info": "description",
"data" : {
"text": "blog",
"date": "date"
}
}
}
but the map object expected by JSONata is like below.
{
"name": title,
"info": description,
"some" : {
"text": blog,
"date": date
}
}
The above JSON key is in Quotes and value without Quotes.
Please find the NodeJS API code.
app.post('/JSONTransform', function(req, res, next)
{
const data = req.body.data;
const map = req.body.map;
var expression = jsonata(map);
var result = expression.evaluate(data);
res.send(result);
});
I can write simple function to remove quotes but the above map is simple example. It can be any no of child object and may have some special character in the value including quotes.
I prefer some npm library or standard way to remove quotes or configure JSONata to accepts quotes in value.
Appreciate if you suggest any other library or option.
This Node JS API is called from ASP.NET Core Web API.
ASP.NET Core Web API gets the data and map from database and pass this as single JSON to Node JS API.
Please suggestion solution to this problem or best alternative.
Thanks
Raj
I found solution to this problem.
Pass the single JSON that has both data and map. Since MAP is not valid JSON, I made entire map as string and escaped doubles quotes which is inside the string.
Please find the sample.
{
"map": "{ \"name\": title, \"info\": description, \"data\": { \"text\": blog, \"date\": date }}",
"data": {
"title": "title1",
"description": "description1",
"blog": "This is a blog.",
"date": "11/4/2013"
}
}

How to include fields in api server and remove it before returning to results to client in Graphql

I have a Node.js GraphQL server. From the client, I am trying get all the user entries using a query like this:
{
user {
name
entries {
title
body
}
}
}
In the Node.js GraphQL server, however I want to return user entries that are currently valid based on publishDate and expiryDate in the entries object.
For example:
{
"user": "john",
"entries": [
{
"title": "entry1",
"body": "body1",
"publishDate": "2019-02-12",
"expiryDate": "2019-02-13"
},
{
"title": "entry2",
"body": "body2",
"publishDate": "2019-02-13",
"expiryDate": "2019-03-01"
},
{
"title": "entry3",
"body": "body3",
"publishDate": "2020-01-01",
"expiryDate": "2020-01-31"
}
]
}
should return this
{
"user": "john",
"entries": [
{
"title": "entry2",
"body": "body2",
"publishDate": "2019-02-13",
"expiryDate": "2019-03-01"
}
]
}
The entries is fetched via a delegateToSchema call (https://www.apollographql.com/docs/graphql-tools/schema-delegation.html#delegateToSchema) and I don't have an option to pass publishDate and expiryDate as query parameters. Essentially, I need to get the results and then filter them in memory.
The issue I face is that the original query doesn't have publishDate and expiryDate in it to support this. Is there a way to add these fields to delegateToSchema call and then remove them while sending them back to the client?
You are looking for transformResult
Implementation details are:
At delegateToSchema you need to define transforms array.
At Transform you need to define transformResult function for filtering results.
If you have ability to send arguments to remote GraphQL server, then you should use
transformRequest

Is it possible to add additional user defined properties other than standard properties in "keen" object?

As for every keen event, keen object gets automatically attached with structure of keen object.
var keen_event = {
"keen": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939"
},
other properties...
}
But I want to add other custom properties in keen object as;
{
"keen": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939",
"event_type" : "some_values",
...
}
}
I tried adding other properties on keen and than encode the keen_event as:
var encodedData = base64.encode(JSON.stringify(keen_event));
The encoded data is then passed on keen api to create an event but I am getting error as : "Invalid property for keen namespace. You used: \'event_type\'".
Is there a solution for that? Is it possible to add custom key value properties other than standard properties on " keen" object while creating an keen event? Thanks in advance.
No, this isn't allowed in the Keen API. The keen namespace is reserved and only a small handful of properties (such as keen.timestamp or keen.addons) may be specified in that namespace when an event is written. The namespace is reserved to allow Keen to add new special-purpose properties in the future and not worry about collisions with user-defined properties. (See also: https://keen.io/docs/api/#the-keen-object.)
Perhaps it's worth stepping back and asking: why do you want to add custom properties to the keen namespace? What would it allow you to do that you couldn't do with, say, my.keen.x or keen_custom.x?
FYI: I'm a platform engineer at Keen :)
var data = {
"keen": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939",
},
"keen1": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939",
},
"keen2": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939",
}
}
var newObj = {}
Object.keys(data).map((element)=> {
var t = {
...data[element],
"event_type" : "some_values",
}
newObj[element] = t
return element
})
console.log(newObj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
This may help
Try something like this
var keenEvent = {
"keen": {
"created_at": "2012-12-14T20:24:01.123000+00:00",
"timestamp": "2012-12-14T20:24:01.123000+00:00",
"id": "asd9fadifjaqw9asdfasdf939"
}
};
keenEvent.keen.myNewProperty = "its value";
keenEvent.keen.myNewProperty2 = "its value2";

Performing a query on the lowest level of a tree-structured Dojo store

Let's say we have a nested data structure like so:
[
{
"name": "fruits",
"items": [
{ "name": "apple" ...}
{ "name": "lemon" ...}
{ "name": "peach" ...}
]
}
{
"name": "veggies",
"items": [
{ "name": "carrot" ...}
{ "name": "cabbage" ...}
]
}
{
"name": "meat",
"items": [
{ "name": "steak" ...}
{ "name": "pork" ...}
]
}
]
The above data is placed in a dojo/store/Memory. I want to perform a query for items that contain the letter "c", but only on the lower level (don't want to query the categories).
With a generic dojo/store/Memory, it's query function only applies a filter on the top level, so the code
store.query(function(item) {
return item.name.indexOf("c") != -1;
});
will only perform the query on the category names (fruits, veggies, etc) instead of the actual items.
Is there a straight-forward way to perform this query on the child nodes, and if there's a match, return all children as well as the parent? For instance, the "c" query would return the "fruits" node with it's "peach" child only, "veggies" would remain intact, and "meat" would be left out of the query results entirely.
You can of course define your own checking method in the store's query method. I don't check if this code runs perfectly, but I guess you could pretty much get what it's meant to do.
store.query(function(item) {
var found = {
name: "",
items: []
};
var children = item.items;
d_array.forEach(children, function(child) {
if (child.name.indexOf("c") != -1) {
found.name = item.name;
found.items.push(child);
}
});
return found;
});
Hope this helps.

Resources