get json value object from mongodb - json

I have formData node that has dynamic jsonObject value in mongodb
{
"_id": {
"$oid": "5a71fea0f36d2848ae4f8f0a"
},
"formData": {
"pages": [
{
"name": "page1",
"questions": [
{
"type": "comment",
"name": "about",
"title": "Please tell us about your main requirements "
}
]
}
]
},
"editorId": "59678e58f36d2842f777bc48",
"datetimeSubmit": "2018/01/15"
}
I write a node API to fetch the data from mongodb, it only display ids, editorI and datetimesubmit nodes, but it ignores the formData(jsondata) field.
const Model = require('./myModel');
module.exports = {
getData: function (callback) {
Model.find({}, (err, jsonObj) => {
callback(null, {
data: jsonObj
})
})
}
}
looks like the model.find() doesn't return jsonObject value?
thanks

got my own question fixed, basically, i should also define the data type as JSON in schema, otherwise, will be ignored.

Related

Access nested JSON in React table

I want to display nested JSON data in a react-table.
I tried it like this:
render() {
const columns = [{
//Not Displaying
Header: 'Owner ID',
id: 'ownerid',
accessor: '_links.customer.href.ownerid', // <- i think this is wrong
Cell: this.renderEditable
},
{
//Displaying
Header: 'Price',
accessor: 'price',
Cell: this.renderEditable
}, {
The data i am getting back and have bound to the table is structured as follows:
[
{
"id": 1,
"date": "20.07.2019",
"price": 3.2,
"customer": {
"ownerid": 1,
"firstname": "John",
"lastname": "Johnson"
}
}
]
Here i am using the columns array:
import ReactTable from "react-table";
<ReactTable data={this.state.offers} columns={columns}
filterable={true} pageSize={10}/>
Binding the data:
fetchOffers = () => {
const token = sessionStorage.getItem("jwt");
fetch(SERVER_URL + 'api/offers',
{
headers : {'Authorization':token}
})
.then((response) => response.json())
.then((responsteData) => {
this.setState({
offers: responsteData._embedded.offers,
});
console.log(this.state);
})
.catch(err=> console.error(err));
}
The data i am using after binding:
Check the Accessors documentation. It has several examples for complex data structure.
I don't see _links or href in your sample data. So I think that you need just:
accessor: 'customer.ownerid'
The data structure from the console screenshot doesn't match your sample data. And it doesn't seem to contain ownerid. Try accessor: '_links.customer.href' to check whether it outputs anything to the table.
I figured it out.
I called the endpoint "localhost:8080/api/offers" and saved the following response:
"offers": [
{
"date": "20.07.2019",
"price": 3.2,
"_links": {
"self": {
"href": "http://localhost:8080/api/offers/1"
},
"offer": {
"href": "http://localhost:8080/api/offers/1"
},
"customer": {
"href": "http://localhost:8080/api/offers/1/customer"
}
}
}
]
there is no customer object
But when i call "localhost:8080/offers" i get:
[
{
"id": 1,
"date": "20.07.2019",
"price": 3.2,
"customer": {
"ownerid": 1,
"firstname": "John",
"lastname": "Johnson"
}
}
]
i changed the URI in my project and now the number is displaying.
I still don't know why i get data from "../api/offers" but i will research.
I had to access a nested object and display it with some styling, and this ended up working for me:
(Note: I was using typescript, so some of the typing might not be necessary)
{
Header: 'Thing To Display',
accessor: 'nested.thing.to.display',
Cell: ({ row }: { row: Row }) => (
<p>{row.values['nested.thing.to.display']}</p>
),
}

json schema validation fails despite correct type

I have a rather large json schema. The problematic part is a smaller schema within the schema called "translations", and which looks like this:
"translations": {
"bsonType": "object",
"patternProperties": {
"id": {
"bsonType": "string"
},
"^[a-z]{2}$": {
"anyOf": [
{
"bsonType": "object"
},
{
"bsonType": "array"
}
]
}
}
}
Where the object defined by the regex contains many more properties (a field called "text", for example) and the array is an array of these objects, but I only left the parts that are important for understanding the structure.
My issue is that when I validate my files against this schema, it fails every single one of them, but when I remove the "bsonType": "object" from the first object in the anyOf array, it works properly.
All of my files are such that at least one of the objects in the translation objects, which have the regular expression as key, are of type "object". so I don't understand why it fails them.
I use mongoDB 3.6.0.
Here is an example for a file that would fail:
"translations":{
"id":"12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
]
}
In case it wasn't clear- the problem is that files like this one fail when the schema is defined with "bsonType": "object" in the first object of the anyOf array, and works when i take that off. The "bsonType": "array" in the second object of the anyOf array works fine.
I think your problem that id collide with the regex try this:
let MongoClient = require('mongodb').MongoClient;
let collectionName = 'translations';
let scheme = {
$jsonSchema:{
"bsonType": "object",
"patternProperties": {
"^id$":{
"bsonType":"string"
},
"^(?!id)([a-z]{2})$": {
"anyOf": [
{
"bsonType": "object"
},
{
"bsonType": "array"
}
]
}
},
}
};
let goodJson ={
"id": "12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
]
};
let badJson ={
"id": "12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
],
"nt": "not_object_or_array"
};
async function run() {
let db = await MongoClient.connect('mongodb://localhost:27017/exampleDb');
let dbo = db.db('mydb');
let collections = await dbo.collections();
let collectionsNames = collections.map(c => c.s.name);
if (collectionsNames.includes(collectionName)) {
console.log('dropping collection');
await dbo.collection(collectionName).drop();
}
console.log('creating collection');
await dbo.createCollection(collectionName, {validator: scheme});
let translationCollection = dbo.collection(collectionName);
console.log('this will validate successfully');
await translationCollection.insertOne(goodJson);
console.log('this will raise validation error because: "nt": "not_object_or_array"');
try {
await translationCollection.insertOne(badJson);
} catch(error) {
console.log(error);
}
await db.close();
}
run();

Getting key and value from JSON with angular2

I am looking for best solution how to work with JSON in my angular2 app.
My JSON is:
{
"rightUpperLogoId": {
"id": 100000,
"value": ""
},
"navbarBackgroundColorIdCss": {
"id": 100001,
"value": ""
},
"backgroundColorIdCss": {
"id": 100002,
"value": ""
},
"translationIdFrom": {
"value": "90000"
},
"translationIdTo": {
"value": "90055"
}
}
This JSON is something like configuration file for UI of app. In my application, I want to get id from rightUpperLogoId, it is 100000. With this id I need to do GET task on my backend REST api and the returned value I would like to set to value. Thank you
You could leverage Rx operators like the flatMap one with Observable.forkJoin / Observable.of.
Here is a sample:
this.http.get('config.json')
.map(res => res.json())
.flatMap(config => {
return Observable.forkJoin(
Observable.of(config),
// For example for the request. You can build the
// request like you want
this.http.get(
`http://.../${config.rightUpperLogoId.id}`)
);
})
.map(res => {
let config = res[0];
let rightUpperLogoIdValue = res[1].json();
config.rightUpperLogoId.value = rightUpperLogoIdValue;
return config;
})
.subcribe(config => {
// handle the config object
});
This article could give you more hints (section "Aggregating data"):
http://restlet.com/blog/2016/04/12/interacting-efficiently-with-a-restful-service-with-angular2-and-rxjs-part-2/

How to return a subcollection (or object) in json without including all attributes

I am using mongoose as JSON Schema and node.js with it. Need not say, I am new to both. I have been struggling through the day to get this thing work for me but couldn't. Finally, the only solution was to get help from some real nice people out here.
Here is my schema definition -
UserName = {
"properties": {
userURL: {
"description": "URL of this resource",
"type": "string"
},
userName : {
"description": "UserName",
"type": "string",
"required": true
},
}
}
When I make a get call to it, it returns the response in following format -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"__v": 0,
"properties": {
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
}
]
Now my requirement is to return the response in following format -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
]
i.e without version and properties tags. I am able to get away with version using following code but properties seems to be tricky thing -
.get(function(request, response) {
UserSchemaModel.find().select('properties.userURL properties.userName').exec (function (err, resObj) {
if (err)
response.send(err);
else{
response.json(resObj);
}
});
});
But it still has properties field :( -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"properties": {
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
}
]
I did some google around select as, alias name in select,population in mongoose but no luck.
Kindly suggest. With best Regards.
Just make a new object
response.json(
{
"_id": resObj["_id"],
"userURL": resObj["properties"]["userUrl"],
"userName": resObj["properties"]["userName"]
}
);
Update: Since resObj is an array (as per your comment), you can use Array.prototype.map() to transform them into the right format like so:
response.json( resObj.map(function(o){
return {
"_id": o["_id"],
"userURL": o["properties"]["userUrl"],
"userName": o["properties"]["userName"]
};
})
);
This will return a list of transformed objects that then get passed into the response.json() method.

Loading TreeStore with JSON that has different children fields

I am having a JSON data like below.
{
"divisions": [{
"name": "division1",
"id": "div1",
"subdivisions": [{
"name": "Sub1Div1",
"id": "div1sub1",
"schemes": [{
"name": "Scheme1",
"id": "scheme1"
}, {
"name": "Scheme2",
"id": "scheme2"
}]
}, {
"name": "Sub2Div1",
"id": "div1sub2",
"schemes": [{
"name": "Scheme3",
"id": "scheme3"
}]
}
]
}]
}
I want to read this into a TreeStore, but cannot change the subfields ( divisions, subdivisions, schemes ) to be the same (eg, children).
How can achieve I this?
When nested JSON is loaded into a TreeStore, essentially the children nodes are loaded through a recursive calls between TreeStore.fillNode() method and NodeInterface.appendChild().
The actual retrieval of each node's children field is done within TreeStore.onNodeAdded() on this line:
dataRoot = reader.getRoot(data);
The getRoot() of the reader is dynamically created in the reader's buildExtractors() method, which is what you'll need to override in order to deal with varying children fields within nested JSON. Here is how it's done:
Ext.define('MyVariJsonReader', {
extend: 'Ext.data.reader.Json',
alias : 'reader.varijson',
buildExtractors : function()
{
var me = this;
me.callParent(arguments);
me.getRoot = function ( aObj ) {
// Special cases
switch( aObj.name )
{
case 'Bill': return aObj[ 'children' ];
case 'Norman': return aObj[ 'sons' ];
}
// Default root is `people`
return aObj[ 'people' ];
};
}
});
This will be able to interpret such JSON:
{
"people":[
{
"name":"Bill",
"expanded":true,
"children":[
{
"name":"Kate",
"leaf":true
},
{
"name":"John",
"leaf":true
}
]
},
{
"name":"Norman",
"expanded":true,
"sons":[
{
"name":"Mike",
"leaf":true
},
{
"name":"Harry",
"leaf":true
}
]
}
]
}
See this JsFiddle for fully working code.