Nested Json from nested mysql queries in Nodejs/ExpressJs - mysql

I m fetching data from mysql database in nodejs/expressjs and want to create nested json from it.
I want to create Json object like this :
[
{id : 1,countryName:'USA',population:10000,
cities : [
{id:1,cityName:'NY',countryId:1},{id:2,cityName:'Chicago',countryId:1}
]
},
{id : 2,countryName:'Canada',population:20000,
cities : [
{id:1,cityName:'Toronto',countryId:2},{id:2,cityName:'Ottawa',countryId:2}
]
}
]
here is my code in expressJs but it is giving me an empty array of JSON
app.get("/checkJson",function(req,res){
var country = {};
var outerobj = {};
var outerArray = [];
conn.query("select * from country",function(err,result){
for(var i = 0 ;i<result.length;i++){
var cityobj = {};
var city = [];
conn.query("select * from city where countryId ="+result[i].id,function(err,cityResult){
for(var j = 0;j<cityResult.length;j++){
cityobj = {cityName:cityResult[j].name,countryId:cityResult[j].countryId};
city.push(cityobj);
} //end city forloop
}) //end city Query
outerobj = {id:result[i].id,countryName:result[i].name,pop:result[i].population,cities:city};
outerArray.push(outerobj);
} //end country forloop
}) // end country query
console.log(outerArray);
})

MySQL returns flat objects. We want to nest joined objects.
Let's say we have courses table, each course belongs to a department and has various course sections. We would like to have a resulting courses array that has a department object property within it and have a list of course sections.
This is a good solution from kyleladd on github
https://github.com/ravendano014/node-mysql-nesting

Related

JSON add nested sub objects dynamically using JS or JQuery

I am creating a services cart at client side
where services are grouped inside 3 level of groupings like
product[SECTION] [SERVICE] [ITEM]
product['carpet']['cleaning']['room'] = {'qty':2,'price':15};
product['carpet']['cleaning']['hall'] = {'qty':1,'price':10};
product['carpet']['protecting']['hall'] = {'qty':1,'price':10};
product['carpet']['deodorize']['hall'] = {'qty':1,'price':10};
product['leather']['cleaning']['sofa'] = {'qty':1,'price':10};
want to generate above structure of json.
my text boxes looks like below notice data-section data-service data-tem and data-price
<input type="text" class="form-control input-number"
data-price="15" data-section="carpet" data-item="room" data-service="protect" />
My JS code is as below, but it adds only current item while overwriting all other services and sections.
$(function(){
$('.input-number').change(function(){
var section = $(this).attr('data-section');
var item = $(this).attr('data-item');
var service = $(this).attr('data-service');
var qty = $(this).val();
var unitprice = $(this).attr('data-unitprice');
addProduct(section,item,service,qty,unitprice);
});
});
function addProduct(section,item,service,qty,unitprice){
let products = {};
if(localStorage.getItem('products')){
products = JSON.parse(localStorage.getItem('products'));
}
products['"'+section+'"'] =
{
['"'+service+'"'] : {
['"'+item+'"'] : {
'unitprice' : unitprice, 'qty': qty
}
}
};
localStorage.setItem('products', JSON.stringify(products));
}
How can I append only instead of overwriting nested items?
EDITED
I have edited my add product function as below but still not getting desired result
function addProduct(section,item,service,qty,unitprice){
let products = {};
if(localStorage.getItem('products')){
products = JSON.parse(localStorage.getItem('products'));
}
var v = {
[service] : {
[item] :{
"qty":qty,'unitprice':unitprice
}
}
};
products.push( section, v );
localStorage.setItem('products', JSON.stringify(products));
}
Object.prototype.push = function( key, value ){
if(typeof value === 'object'){
var k = Object.keys(value)[0];
value.push( k, value[k] );
}
this[ key ] = value;
return this;
}
First of all that is not a good way to store your data.
Here's a better way to store your data.
It's much more easy to understand if you see it like an object cause in javascript it's the same thing
//example this 2 data is store the same way in javascript
var product['carpet']['cleaning']['room'] = {'qty':2,'price':15};
var product = [{
carpet: {
cleaning: {
room: {'qty':2,'price':15}
}
}
}]
// my solution would be just save section, service and item in the object, example:
var product = [];
var v = {
section: 'carpet',
service: 'cleaning',
item: 'room'
qty:2,
price:15
}
product.push(v)

parsing JSON embedded structure

My JSON response comes like below:
"channels": {
"BB0AC397-78AA-41C9-818A-A52A6BC81E9B": {
"id": "BB0AC397-78AA-41C9-818A-A52A6BC81E9B",
"name": "MyVABotChannel",
},
"94612845-7868-4B1C-8E58-7BD88869B197": {
"id": "94612845-7868-4B1C-8E58-7BD88869B197",
"name": "System_Bot_Test",
}
my requirement is to extract the id of the structure where name is MyVABotChannel. the id are not fixed and random when they will come from server. so how do i find the id corresponding to the specific name.
Assuming javascript
This snippet assumes multiple entries with "MyVABotChannel"
// response = JSON
var values = Object.values(response.channels);
var botChannels = values.filter(channel => channel.name === "MyVABotChannel");
This snippet assumes one entry with "MyVABotChannel"
// response = JSON
var values = Object.values(response.channels);
var botChannels = values.find(channel => channel.name === "MyVABotChannel");
If it's in JavaScript or any library that exposes a JSON DOM, then like so:
var channels = ...
var key = Object
.getKeys( channels )
.find( e => chanels[e].name == "MyVABotChannel" );
if( key == null ) {
console.log("Couldn't find element.");
return;
}
var result = channels[key].id;
console.log( result );

How to get property from JSON model filled with oData?

Im trying to get property from oData return model. I set data in success callback function from oData to JSON model.
oODataModel.read("/ConnObjSet?$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'",
true,
true,
false,
function _OnSuccess(oData, oResponse){
var oJSON = new sap.ui.model.json.JSONModel();
oJSON.setData(oData);
sap.ui.getCore().setModel(oJSON, "ConnectionObject");
},
This is my JSON object in console log and highlighted property I want to get. I want to get every 15 Buspartner number from whole array.
And this is what I tried to get property:
var oLog = sap.ui.getCore().getModel("ConnectionObject").oData.results;
console.log(oLog);
If you have an array of objects, you can get an array of properties from each of these objects by using the Array.map() function.
So in your case:
var aResults = this.getView().getModel().getProperty("/results");
var aBuspartner = aResults.map(function (r) { return r.Buspartner});
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray", aBuspartner)
Please try:
var aResults = this.getView().getModel().getProperty("/results");
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray",new Array())
for(var i = 0; i<aResults.lenght;i++){
oJSONModel.getProperty("/resultarray").push(aResults[i].Buspartner)
}
You could also try to add a filter and select to your oData.read
The oData-URL
http://services.odata.org/V2/Northwind/Northwind.svc/Products
selects all Product with all their properties
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$filter=UnitsInStock%20eq%2017
shows only Products with "UnitsInStock=17"
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$select=ProductID&$filter=UnitsInStock%20eq%2017
selects only the ProductID of Products with "UnitsInStock=17"
so
oODataModel.read("/ConnObjSet?$select=Buspartner&$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'"
...
should get the filtered Buspartners directly.

Parsing Google Maps JSON data for Geocoding in JQ (Not JQuery)

I am trying to get the Country and City names from Lat and Long values with JQ.
Here is the full example JSON
https://maps.googleapis.com/maps/api/geocode/json?latlng=55.397563,10.39870099999996&sensor=false
I pasted returned JSON in jqplay,
Tried to select Country and City names, but the closest I get is
.results[0].address_components[].short_name
How can I specify just bring the nodes where "types" : [ "country", "political" ] ?
Thanks
It's unclear to me what exactly you're looking for. Each result has a set of types, each address component also has a set of types. Which one did you want? We can write a filter that will match what you attempted but considering the data, it will be completely useless to you. The only item that contains the types you listed is just a country name.
Anyway, assuming you wanted to get a result object that had the types "country" and "political", use the contains() filter.
.results | map(
select(
.types | contains(["country","political"])
)
)
Otherwise you'll need to clarify what exactly you wanted from this data set. An example of the expected results...
I wrote a function to do this.
/**
* geocodeResponse is an object full of address data.
* This function will "fish" for the right value
*
* example: type = 'postal_code' =>
* geocodeResponse.address_components[5].types[1] = 'postal_code'
* geocodeResponse.address_components[5].long_name = '1000'
*
* type = 'route' =>
* geocodeResponse.address_components[1].types[1] = 'route'
* geocodeResponse.address_components[1].long_name = 'Wetstraat'
*/
function addresComponent(type, geocodeResponse, shortName) {
for(var i=0; i < geocodeResponse.address_components.length; i++) {
for (var j=0; j < geocodeResponse.address_components[i].types.length; j++) {
if (geocodeResponse.address_components[i].types[j] == type) {
if (shortName) {
return geocodeResponse.address_components[i].short_name;
}
else {
return geocodeResponse.address_components[i].long_name;
}
}
}
}
return '';
}
The way to use it; an example:
...
myGeocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results[1]) {
var country = addresComponent('country', results[1], true);
var postal_code = addresComponent('postal_code', results[1], true);
...
}
});
...
I used it here: saving marker data into db
Assign the json to results variable, var results = {your json}.
Then try this :
for( var idx in results.results)
{
var address = results.results[idx].address_components;
for(var elmIdx in address)
{
if(address[elmIdx].types.indexOf("country") > -1 &&
address[elmIdx].types.indexOf("political") > -1)
{
address[elmIdx].short_name //this is the country name
address[elmIdx].long_name //this is the country name
}
}
}

How can i create sql-like AS3 ArrayCollection grouping

I have an arrayCollection which I created dynamically like one at bottom:
arrCol = ({"ID":ids[i][0], "Price":ids[i][1], "OtherInfo":ids[i][2]});
I want to group data and summarise Price by ID.
If this ArrayCollection was a SQL table, I could use a query like this:
SELECT ID, SUM(Price), OtherInfo
FROM TableA
GROUP BY ID
So how can I set an AS3 function like the query example in SQL or is there any native ArrayCollection class for this?
Try this, there is no built in function available for your need(sum,groupby) so we need to do manually below code will help you.
var arrCol:ArrayCollection = new ArrayCollection();
arrCol.addItem({"ID":1, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":1, "Price":700, "OtherInfo":"info"});
arrCol.addItem({"ID":2, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":2, "Price":200, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":400, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":100, "OtherInfo":"info"});
var dic:Dictionary = new Dictionary();
for each (var item:Object in arrCol)
{
if(!dic[item.ID]){
dic[item.ID] = item;
}
else{
var oldSumObj:Object = dic[item.ID];
oldSumObj.Price +=item.Price;
dic[item.ID] = oldSumObj;
}
}
var groupedList:ArrayCollection = new ArrayCollection();
for each (var itemObj:Object in dic)
{
groupedList.addItem(itemObj);
}
output will be:
"groupedList" mx.collections.ArrayCollection (#27af939)
[0] Object (#8836569)
ID 1
OtherInfo "info"
Price 800 [0x320]
[1] Object (#87a7c71)
ID 2
OtherInfo "info"
Price 300 [0x12c]
[2] Object (#87a7bc9)
ID 3
OtherInfo "info"
Price 600 [0x258]
While you can't make SQL type queries in AS3, you can use its bevy of methods to achieve the same result.
// Work with an array. Child elements must be an associative array (structure/object/hash-table)
var ac:Array = [
{"name":"apple", "price":100, "color":"red"},
{"name":"banana", "price":50, "color":"yellow"},
{"name":"pear", "price":250, "color":"green"},
]
// Apply the order your want based on the property you're concerned with.
ac.sortOn("price", Array.ASCENDING)
// If necessary, create a subset of that array with the "select"-ed columns.
var output:Array = [];
for each (var entry:Object in ac) {
output.push({entry.name, entry.color});
}
// Printing output will result in
// 0:{"name":"banana", "color":"yellow"},
// 1:{"name":"apple", "color":"red"},
// 2:{"name":"pear", "color":"green"}