display meteor aggregation Json data in google charts - meteor

Iam a newbie for meteor and google charts, want to display the google chart with meteor mongodb aggregate Json data. To start with i have a static json data but for some reason the google visulization datatable returning empty. the following is the Client.js code.
Template.GooglechartsPie.onRendered(function () {
console.log("iam from render function")
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart'], callback: drawChart});
function drawChart() {
var jsonData = '[{"_id":"Household","totalAmount":520},{"_id":"Insurance","totalAmount":235},{"_id":"Family","totalAmount":1358},{"_id":"Utilities","totalAmount":5371.5},{"_id":"Automobile","totalAmount":500},{"_id":"Home Office","totalAmount":290},{"_id":"Travel","totalAmount":14},{"_id":"Food","totalAmount":303}]'
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
console.log("my data" + JSON.stringify(data))
//returning my data"{\"cols\":[],\"rows\":[]}" -- not sure why no data here
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('Googlechart'));
chart.draw(data, {width: 400, height: 240});
}
}

Your JSON should be formatted like this
{
"cols": [
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"Mushrooms","f":null},{"v":3,"f":null}]},
{"c":[{"v":"Onions","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Olives","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Zucchini","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Pepperoni","f":null},{"v":2,"f":null}]}
]
}
So when you're trying to convert your JSON to a DataTable you're not getting any returns as it isn't correctly formatted. More to read here.
Try formatting your JSON like
var jsonData = {}
jsonData.cols = [
{"label":"ID", "type":"string"},
{"label":"Value", "type":"number"}
]
jsonData.rows = [
{"c":[{"v":"Household"}, {"v":520}]},
{"c":[{"v":"Insurance"}, {"v":200}]}
]

Related

How can I restore a DynamoDB backup to a local DynamoDB instance/container?

I've taken a backup of a DynamoDB table in the AWS Console. I was able to download the file locally. I'd like to take that file and import it into a local dynamodb instance for testing. I've got far enough to create the table, however the backup json format doesn't seem to match nicely to the .NET AWS SDK APIs (thats a lot of TLAs).
Example backup contents:
{"Item":{"Attributes":{"M":{"createdAt":{"N":"1611923095468"},"eventDate":{"S":"2021-01-30T17:00:00.000Z"} }},"PartitionKey":{"S":"1234"},"SortKey":{"S":"1"}}}
{"Item":{"Attributes":{"M":{"createdAt":{"N":"1611923095468"},"eventDate":{"S":"2021-01-30T17:00:00.000Z"} }},"PartitionKey":{"S":"1234"},"SortKey":{"S":"2"}}}
The .NET APIs seem to want to convert the JSON in the non-dynamodb attribute format, so expect it like this:
{
"Item": {
"Attributes": {
"createdAt": "1611923095468",
"eventDate": "2021-01-30T17:00:00.000Z"
},
"PartitionKey": "1234",
"SortKey": "1"
}
}
So, I'd like to do something like:
var json = "{}"; // ORIGINAL CONCATENATED JSON FROM ABOVE
Document.FromJson(json)
Is there some API that I'm missing that can convert this into some format that I can load into dynamodb? Again, using .NET, but open to any tools/utils for this.
This is the js script I came up with. Seemed to do the trick:
var DDB = require("#aws-sdk/client-dynamodb");
var fs = require('fs');
const ddb = new DDB.DynamoDB({ region: 'local', endpoint: 'http://localhost:8000' });
(async function test() {
const text = fs.readFileSync('./bmorer2e5e3pfflf7qmuhhnpwy.json', 'utf8');
text.toString().split('\n').map(async (line) => {
if (line) await saveLine(line)
});
})();
async function saveLine(line) {
let item = JSON.parse(line);
item.TableName = 'TABLE_NAME';
item.ReturnConsumedCapacity = 'TOTAL';
const res = await ddb.putItem(item);
console.log(res.ConsumedCapacity);
}

How do I add/delete array elements on a Firestore document via REST?

I want to use an array to store temperature readings from an Arduino on a Firestore database. My (probably terrible) way of thinking it out so far is to read the document, do my array operations on the Arduino, and send the whole array back to Firestore. I don't know how to write to Firestore via REST at all so I haven't implemented it yet. Here is my code:
void writeTemp(String url, int temperature) {
// writeTemp() appends the given temperature to an array. temperature[0]
// holds the oldest temperature while temperature[9] holds the first.
// When a new temperature is put in, the last one is taken out.
HTTPClient http;
http.begin(url);
int httpCode = http.GET();
// Gets the current temperature array from the provided URL.
String payload = http.getString();
Serial.println(httpCode); // Prints HTTP response code.
// Calculates the size of the JSON buffer. This is big enough for 11
// temperature values that are all 3 digits so as long as you're not using
// this on the Sun you're probably fine.
const size_t capacity = JSON_ARRAY_SIZE(11) + 14 * JSON_OBJECT_SIZE(1) +
JSON_OBJECT_SIZE(4) + 440;
DynamicJsonDocument doc(capacity); // Makes the JSON document
DeserializationError err = deserializeJson(doc, payload);
// Prints out the deserialization error if an error occurred
if (err) {
Serial.print("JSON DESERIALIZE ERROR: ");
Serial.println(err.c_str());
}
// Sets up the array from the JSON
JsonArray temperatureArray =
doc["fields"]["Temperature"]["arrayValue"]["values"];
// Creates a new array object to store the new temperature
JsonObject newTemp = temperatureArray.createNestedObject();
// Puts the new temperature in the new array object. For some reason,
// Firestore stores numbers as strings so the temperature is converted into
// a string.
newTemp["integerValue"] = String(temperature);
// Removes the first (oldest) array object.
temperatureArray.remove(0);
// Removes irrelevant data that we got from the Firestore request
doc.remove("name");
doc.remove("createTime");
doc.remove("updateTime");
String newJson;
serializeJson(doc, newJson);
Serial.println(newJson);
}
How would I send this new JSON back to Firestore? Am I even doing this right? I've heard of transactions, which sounds like the theoretically better way to do what I'm trying to do but I can't find any guides or readable documentation on how to do it. My database is in test mode right now so no need to worry about authentication.
The documentation for the Firestore REST API is here.
To create a document, you need to issue a POST Request to an URL with the following format:
https://firestore.googleapis.com/v1/{parent=projects/*/databases/*/documents/**}/{collectionId}
With an instance of a Document in the Request body.
To be more concrete, below is an example in a simple HTML page (using the Axios library to issue the HTTP Request). This code will create a new document in the collection1 Firestore collection.
Just save this file on your local disk, adapt the value of <yourprojectID> and opens this page in a browser, directly from your local disk.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
var firebaseProjectId = '<yourprojectID>';
var collectionId = 'collection1';
var url =
'https://firestore.googleapis.com/v1/projects/' +
firebaseProjectId +
'/databases/(default)/documents/' +
collectionId;
var writeObj = {
fields: {
name: {
stringValue: 'theName'
},
initialBudget: {
doubleValue: 1200
}
}
};
axios.post(url, writeObj).catch(function(error) {
console.log(error);
});
</script>
</body>
</html>
In order to update an Array in an existing document, you have to use a FieldTransform with appendMissingElements elements.
Excerpt of this doc on appendMissingElements elements:
appendMissingElements: Append the given elements in order if they are not already present in the current field value. If the field is not an array, or if the field does not yet exist, it is first set to the empty array.
You will find below an example of FieldTransform value containing appendMissingElements elements.
{
"transform": {
"document": "projects/" + firebaseProjectId + "/databases/(default)/documents/....,
"fieldTransforms": [
{
"setToServerValue": "REQUEST_TIME",
"fieldPath": "lastUpdate"
},
{
"appendMissingElements": {
"values": [
{
"stringValue": "...."
}
]
},
"fieldPath": "fieldName"
}
]
}
}
UPDATE FOLLOWING YOUR COMMENT
The following should work (tested positively):
var collectionId = 'SensorData';
var url =
'https://firestore.googleapis.com/v1/projects/' +
firebaseProjectId +
'/databases/(default)/documents:commit';
var writeObj = {
writes: {
transform: {
document:
'projects/' +
firebaseProjectId +
'/databases/(default)/documents/' +
collectionId +
'/Temperature',
fieldTransforms: [
{
setToServerValue: 'REQUEST_TIME',
fieldPath: 'lastUpdate'
},
{
appendMissingElements: {
values: [
{
integerValue: 25
}
]
},
fieldPath: 'Temperature'
}
]
}
}
};

Added field not published to client?

I'm doing an aggregation in Meteor where I'm trying to find 'thingies' within a given distance and publish it to the client:
Meteor.publish("thingieSearch", function(userId) {
check(userId, String);
var subscription = this;
var thingies = {};
var userId = this.userId;
var usrAcc = Meteor.users.findOne({_id: userId});
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var pipeline = [{
$geoNear: {
near: usrAcc.profile.location.geometry.coordinates,
distanceField: "calculatedDistance",
spherical: true,
limit: 100,
distanceMultiplier: 3959.2,
maxDistance: 0.075,
query: {
"status": "started",
"owner": {$ne: userId} },
}
}];
db.collection("thingies").aggregate(
pipeline,
Meteor.bindEnvironment(
function (err, result) {
console.log('result', result);
_.each(result, function (r) {
chases[r._id] = r;
subscription.added("thingieSearch", r._id, {
chase: r
});
})
}
)
);
subscription.ready();
});
When I do a console.log on the server side, it looks correct, the 'distanceField' that I specified as 'calculatedDistance' is calculated and shown as a field.
On the client side, I subscribe to this publication and I can see the thingies but I can't see the 'calculatedDistance' field.
Any idea why?
There are two things here.
1) Your publication will not reactively update data to the client, since you are using mongodb remote collection driver. If you intend it to be a non-reactive then you can use a meteor method instead of publication and call the method whenever userId changes.
2) I think you are using thingies collection on the client side and not seeing the calculatedDistance field. You need to create a client only collection (thingieSearch) to access the custom published results like this,
//On client side only
thingieSearch = new Mongo.Collection("thingieSearch");
thingieSearch.findOne(); // After the publication, you should be able to see the results with calculatedDistance
You should use whatever name you passed inside the subscription.added block to create collection. For example, if your publication has
subscription.added("thingieWithCalculateField", r._id, { chase: r });
you should do
//On client side only
thingieWithCalculateField = new Mongo.Collection("thingieWithCalculateField");
// instead of thingieSearch = new Mongo.Collection("thingieSearch");
See the counts-by-room publication in the Meteor.publish documentation for more details.

Unable to add data into Firebase

Im getting the following two errors when trying to upload my JSON into Firebase:
Console error
Factory:
angular
.module("ngClassifieds")
.factory("classifiedsFactory", function($http, $firebaseArray){
(
var ref = new Firebase('https://xxxxx.firebaseio.com/');
return {
ref: $firebaseArray(ref)
}
});
Controller:
.controller("classifiedsCtrl", function($scope, $http, classifiedsFactory, $mdSidenav, $mdToast, $mdDialog)
I am using the following code to upload my JSON into firebase.
var firebase = classifiedsFactory.ref //we have a variable pointing to our classifiedsFactory reference
angular.forEach(data, function (item) {
firebase.$add(item);
});
Please let me know where I'm going wrong here.

Json page with collection data

i am very new to nodejs and meteor. i need to create a page content-type application/json and data from mongo collection. So when collection data change json page must be change.
For json page i use this example:
https://stackoverflow.com/a/23666992/1446182
if (Meteor.isServer) {
Meteor.startup(function () {
try{
var interval = Meteor.setInterval(function() {
var result = Meteor.http.call("GET", "http://192.168.2.144//ihale/meteorGetPage" );
var resultJson = JSON.parse(result.content);
var json = IhaleCollection.findOne();
IhaleCollection.update(json, {$set: {json: resultJson}});
}, 1000);
}
catch(err) {
console.log(err);
}
});
Router.map(function() {
this.route('jsonExample', {
where: 'server',
path: '/json',
action: function() {
var obj = IhaleCollection.findOne();
var headers = {'Content-type': 'application/json'};
this.response.writeHead(200, headers);
this.response.end(JSON.stringify(obj));
}
});
});
}
When Meteor.startup i start to update IhaleCollection every second.
So how i can update json page when IhaleCollection change?
You can't. Not this way anyway. JSON has no builtin mechanism to detect if the source has changed and given that the router endpoint is outputting raw JSON data with no javascript, no automatic updates will happen. Only when a client refreshes the endpoint will there be an update.
Meteor deals with reactive data by inserting javascript in the underlying html page. If you want to utilize that then you have to write a template, write a helper method to return JSON and use the helper method in the body.
The helper method should look something like this:
Template.jsondoc.helpers{(
json: function(){
return JSON.stringify(IhaleCollection.findOne());
}
})
Template can be as simple as that:
<template name="jsondoc">
{{json}}
</template>
and your route will be as simple as this:
Router.route('/jsondoc');

Resources