Trying to get data from another table, snapshot is null - node.js

I'm trying to get data from another table using a cloud function and it's telling me the snapshot is null.
I have a Firebase database that I have some IoT devices connected to. They update their respective tables(I hope that's the right word) in the database (device_001, device_002, device_003) and send on to the external API I am using, that works which are great.
Now I need to get the devices to look up where they are, I have set up another table which each contain their id, location, and timestamp.
Lookup table structure:
devices
device_001
id: ...
location: ...
timestamp: ...
Code:
exports.devices_Listener = functions.database.ref('/devices/{deviceId}/{entryId}').onWrite(snapshot => {
object = snapshot.after.val();
getCurrentLocation();
process();
return null
})
function getCurrentLocation() { functions.database.ref('locations/{deviceId}').limitToLast(1).once('value').then(function(snapshot) {
var o = snapshot.val();
})
}
I expected this to get the snapshot and allow me to get the location so I can store it with the processed data (that's all working so not included here).
When I try to get the location field I get can't read the property 'location'
and when I try to just log the snapshot to the console it tells me it is null.
I can't see what I've done wrong here but I'm sure it's small and simple.
Thanks for taking the time to read this nonsensical mess.

Related

Mutator runs on update but cell data unchanged

I want to create a new field reservationAction and put into my table as a column Reservation defined as:
{title: "Reservation", field: "reservationAction", mutator: reservationMutator},
with reservationMutator as:
var reservationMutator = function(value, data, type, params, component) {
console.log(data);
if (!data.checkoutable) return null;
if (data.is_reserved) {
return "Free";
}
return "Get";
}
is_reserved and checkoutable are pre-existing fields of my data.
When the page initially loads, and table is created using ajax, the cell shows the correct string for Reservation. When is_reserved is changed server-side, I call table.updateOrAddData([newData]) (as part of websocket event-handler).
The problem:
When table.updateOrAddData([newData]) run, I can see the custom mutator get triggered
and from the console.log() line, see that the reservationAction is correctly set in the log. But the table itself is showing the old value. Other (non-mutating) columns are updated on the table as expected. Am I missing something or is this a bug?
If instead I use table.replaceData(), then both console, and table show correct value. But I would want to avoid doing this on each websocket event for performance reasons.
Version: I've tried all 5+.
Any help would be appreciated!
jsfiddle
Don't know if this is a workaround or how I'm actually supposed to do it in the first place but, doing row.reformat() seems to do what I expect. Oh well.
table.updateOrAddData([row_obj])
.then(function(rows){
rows.forEach(row => {
row.reformat();
});
});

Can't access unique identifier for Bixby using code from docs

To access a unique identifier for Bixby, I'm trying to access the contactId field within the contact library (which is also viv.self I think?). I tried using the code snippet found in the docs here, but I'm getting some errors.
Code Snippet (Source)
text (Name) {
extends (contact.StructuredName)
}
Errors
ERROR: invalid capsule alias contact
ERROR: unknown super-type: contact.contactId
I would ultimately like to do something like this
integer (Identifier) {
extends (contact.ContactId)
}
Would appreciate any help on accessing this data!
I ended up finding another way to get a device identifier from these docs. There's also a sample capsule here.
In your corresponding JavaScript file, access the $vivContext.locale parameter to return the locale information.
module.exports.function = function accessVivContext (dummyInput, $vivContext) {
var result = "Testing Access vivContext..."
// See docs for all the properties of $vivContext
result = $vivContext.userId
return result
}
You would then need to configure your endpoints for this action like below, including making sure that you set up the proper accepted-inputs for your endpoint:
action-endpoint (AccessVivContext) {
accepted-inputs (dummyInput, $vivContext)
local-endpoint ("AccessVivContext.js")
}

Table-Scraper Not Returning Data Before Function Returns

I am currently working on a Discord bot, which uses node.js, to scrape info from Dododex.com, a database of creatures from the game ARK. I found a very useful library called table-scraper which scrapes tables from web pages and returns the data as an object (or array of objects for multiple tables). In the background, table-scraper uses another library called x-ray, along with the common web request-maker request. Keep in mind that I don't know that much about node or how request works.
What I have working is asking the user for the name of a creature to get the data for. I then check that name against a list of creatures (that I have in a file/JSON object) to see if that name is valid.
Now, what I want to get working is to scrape the relevant data from the dododex page belonging to that creature using table-scraper. Table-scraper is definitely working with dododex, but when I call it to gather the data and put it into an object, it seems to start scraping, but then lets the function return with an empty object. If the program didn't crash right after the return (caused by the attempt to access an empty object), I know from testing that it would finish scraping, even though the function the scraping was called in has already finished.
Here's where the relevant code starts:
const creature = getDinoFromName(args[0].toLowerCase(), arkdata); //Function explained below
if(creature.health.base == 404) //If the creature's name is invalid, getDinoFromName() will return a creature with health.base = 404
{
console.log("unknown");
unknownCreature(args, msg); //Tells the user that the creature is unknown
return;
}
else
{
//Outputs the data
}
And here's where the data gets gathered:
function getDinoFromName(name, arkdata)
{
for(let i = 0; i < arkdata.creatures.length; i++) //Loops through arkdata, a json object with the possible names of all the creatures
{
if(arkdata.creatures[i].possible_names.includes(name)) //If the name the user provided matches one of the possible names of a creature (creatures can have multiple possible names, i.e. rex, t-rex, tyrannosaurus rex)
{
var creature;
console.log("found");
tableScraper.get("http://www.dododex.com/taming/" + arkdata.creatures[i].possible_names[0]).then(function(tableData)
{
console.log("scraped");
var stats = tableData[1]; //tableData is an array of 3 tables matching the 3 html tables found on the site, tableData[1] is the one with the creature's stats. It looks like this: http://ronsoros.github.io/?31db928bc662538a80bd25dd1207ac080e5ebca7
creature = //Now the actual creature object, parsed from tableData[1]
{
"health":
{
"base": stats[0]["Base (Lvl 1)"], //
"perwild": stats[0]["Increase Per Lvl (Wild)"],
"pertamed": stats[0]["Increase Per Lvl (Tamed)"]
}
//There is more data to parse but I only included hp as an example
}
});
return creature;
}
}
//If the creature name is not found to be one of the possible names, returns this to signify the creature was not found
return {"health":{"base":404}};
}
Running the code result in node crashing and the error
/app/server.js:320
if(creature.health.base == 404)
TypeError: Cannot read property 'health' of undefined
at stats (/app/server.js:320:15)
at Client.client.on.msg (/app/server.js:105:7)
Something wonky is going on here, and I really can't figure it out. Any help is appreciated.

Data tracking in DocumentDB

I was trying to keep the history of data (at least one step back) of DocumentDB.
For example, if I have a property called Name in document with value "Pieter". Now I am changing that to "Sam", I have to maintain the history , it was "Pieter" previously.
As of now I am thinking of a pre-trigger. Any other solutions ?
Cosmos DB (formerly DocumentDB) now offers change tracking via Change Feed. With Change Feed, you can listen for changes on a particular collection, ordered by modification within a partition.
Change feed is accessible via:
Azure Functions
DocumentDB (SQL) SDK
Change Feed Processor Library
For example, here's a snippet from the Change Feed documentation, on reading from the Change Feed, for a given partition (full code example in the doc here):
IDocumentQuery<Document> query = client.CreateDocumentChangeFeedQuery(
collectionUri,
new ChangeFeedOptions
{
PartitionKeyRangeId = pkRange.Id,
StartFromBeginning = true,
RequestContinuation = continuation,
MaxItemCount = -1,
// Set reading time: only show change feed results modified since StartTime
StartTime = DateTime.Now - TimeSpan.FromSeconds(30)
});
while (query.HasMoreResults)
{
FeedResponse<dynamic> readChangesResponse = query.ExecuteNextAsync<dynamic>().Result;
foreach (dynamic changedDocument in readChangesResponse)
{
Console.WriteLine("document: {0}", changedDocument);
}
checkpoints[pkRange.Id] = readChangesResponse.ResponseContinuation;
}
If you're trying to make an audit log I'd suggest looking into Event Sourcing.Building your domain from events ensures a correct log. See https://msdn.microsoft.com/en-us/library/dn589792.aspx and http://www.martinfowler.com/eaaDev/EventSourcing.html

Couchdb and Sofa Help

I'm new to Couchdb just a few week back I git clone the couchdb app called sofa [what and app] . Over the week It was going great but suddenly today I stumble upon something.
Here what I meant
when I browse the Sofa app and try to create a Post without the title
it prompt with and alert box "The document could not be saved: The database could not be created, the file already exists." which was weird as looking at the source I found that the require (in validate_doc_update.js return its custom json error) something like in this format {"forbidden" : message }) with forbidden as key
v.forbidden = function(message) {
throw({forbidden : message})
};
v.require = function() {
for (var i=0; i < arguments.length; i++) {
var field = arguments[i];
message = "The '"+field+"' field is required.";
if (typeof newDoc[field] == "undefined") v.forbidden(message);
};
};
in validate_doc_update.js
if (newDoc.type == 'post') {
if (!v.isAuthor()) {
v.unauthorized("Only authors may edit posts.");
}
v.require("created_at", "author", "body", "format", "title");
inspecting the response state that the json returned was found to be different from the json had it would have been return by the above require function in validate_doc_update.js
here is the json
{"error":"file_exists","reason":"The database could not be created, the file already exists."}
This make be believe that the validation in validation_doc_update.js only execute during updating of document
to Prove this point I try to update a document without the title, expecting that it would return the error but surprisingly the document just got saved
so Here are my Question regarding all the Point I mention above
Does validate_doc_update.js "validate" work only during updation of document
if YES
then
how can I manage to succeed in updating a post without the error [Weird bypassing the Validation Completely] . + How can execute validation on create of a document
if NO
then
What is the Error {"error":"file_exists","reason":"The database could not be created, the file already exists."} that is prevent a document to be saved
Can anyone please share light on all the questions listed here
Yes, the validate_doc_update functions are run only when updating documents (include creation and deletion).
The function you show here will allow a document without a title as long as its type is not "post". If you could include the actual request you attempted, I could confirm it.
Finally, the ""The database could not be created" is because you are attempting to create the database (by doing PUT /dbname/ instead of PUT /dbname/docid, I would guess) when it already exists. Again, if you would include the actual request, I could confirm that too.

Resources