Mongoose Post Hook for create() rather than update() - javascript

Maybe I'm misunderstanding, but everything I can find for having a post hook for create() on a mongoose model brings up the update() method instead. Are create() and update() the same?
What I want to do is when a User document is created, send a welcome email, without having to manually call the method on every route/controller that creates a user.
I understand a little about pre- and post- hooks, and I have a pre-remove hook:
userSchema.pre('remove', async function() {
for (let response of this.responses) {
Response.findByIdAndRemove(response);
};
});
But I can't find anything within mongoose docs for a post-hook for create().
If create() and update() are the same, what stops this welcome email from being sent any time the user's information is changed? I only want this to send once, at the very beginning.
Let me know if I'm clear as mud

I found the answer, finally, in the Mongoose docs in a roundabout way through a github feature request: schema.queue: http://mongoosejs.com/docs/api.html#schema_Schema-queue
So I define the method(s) that I want to execute at the time the document is instantiated, then just use the schema.queue command like so:
schema.queue('methodName',[args]);
For the time being, I left the args array empty because they're only operating on themselves, so no other information needs to go in.
The docs don't say it specifically, but I would assume since declaring methods looks to be the same as declaring any function, the queue method can be called before or after declaring the method it calls, but I played it safe and put it after.
Man, this is exciting.

Related

Javascript prompt vs custom prompt. (chessboardjs promotion)

backstory: In chessboardjs you load the board with callback functions for specific events. Chess mechanic that gives me problem is the promotion. I need to hold my callback, prompt a user for a piece he wants to promote to, check if it is a valid move and return('snapback') or execute the move.
Stupid solution: If I prompt with classic
promoPiece = prompt();
everything works, but it looks kinda ugly.
Failed solution: But when I try to create a promise that attaches a callback to my overlay element, to get user click on specific piece I fail(i need to make function async to use promises). I try to get the piece as
async function onDrop(args)
{
..code..
promoPiece = await promoPrompt();
..code..
if(invalid())
{return 'snapback'}
}
and the promotion mechanic works, but the return snapback statement does not work because now the promise is returned instead of a string and it is not accepted with the chessboardjs...(I assumed, I did not dig into source)
Question: 1)How does prompt differ from my solution? 2)How does it work? 3)How can i create a custom promotion handler for a synchronous callback? 4)Can i use promoPrompt.then(myResolve) syntax without making onDrop() async?
It is synchronous
Natively (i.e. the code is part of the browser and exposed as an API via the prompt function)
You can't (unless it is just a wrapper around prompt but then you get the native look and feel that you dislike)
Well, yes, but the value will won't be available until that future so you can't return it to the calling function
If you want a custom UI here, then the calling function needs to be able to handle it asynchronously.

Cloud Function stuck in an infinite loop

exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {
event.data.adminRef.update({"timeSnapshot":Date.now()})})
It appears that Date.now() causes an infinite loop in the function because the following does not:
exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {
event.data.adminRef.update({"timeSnapshot":"newString"})})
How do I fix this?
If you write back to the same location in the database that was previously changed, you can expect this sequence of events:
Function is triggered with the first change from the client
Function writes back to the database
Function is triggered a second time because of the write during step #2
All writes to the database that match the filter path, even those from within the same function, will trigger the function.
In step 3, you need a strategy to figure out if the second function invocation should result in yet another write back to the database. If it does not require another write, the function should return early so that it won't trigger another write. Typically you look at the data in the event passed to the function and figure out if it was already modified the first time. This could involve looking to see if some flag is set in the database, or if the data you modified does not need any more changes.
Many of the code samples provided by the Firebase team do this. In particular, look at text moderation. Also, there is a video that describes the problem and a possible solution. In the end, you're responsible for coming up with the strategy that meets your needs.
I think the following should work fine :-
exports.addNewValue = functions.database.ref('/path/timeSnapshot')
.onWrite(event => { event.data.adminRef.set(Date.now()) })
The logic behind the above is that when you put a trigger function on a higher node (such as /path in your case), then the function would be fired each time a change is made to any of its child nodes (/timestamp in your case) - hence, the infinite loop.
Therefore, as a general practice, for efficiency as well as cost effectiveness, make sure that your trigger function has the lowest possible path node. Flatting out your data really helps in this as well.
If you arrived here having problems with querying try using .once('value') ... it will mean that you only look at the reference point once ... i.e.
ref.orderByChild("isLive").equalTo(true).once("value" , function(snapshot) {
instead of
ref.orderByChild("isLive").equalTo(true).on("value", function(snapshot) {
as the second will have you listening all the time, and when data changes at the ref, the listener will receive the changes and run the code inside your block again

how javascript's animation works in google T-rex game?

I'm wondring how t-rex game (google) actually animate with this code.
Specifically, i had a look at the code and trying to understand how it animate.
As far as i know, the update function(which is prototype in the source file) should be called over and over to make animation happen.
However, i can't see anything that calls update function several times.
And this source code is written with self-invoking function and there is a constructor called Runner at the beginning of the code. My question is does this constructor get called by itself?
To sum up my question,
With this code, can anyone explain how animation actually work? is there any way for Runner's prototype( you can find it if you see the source code on links) to be called from browser or whatever..?
And, when self invoking function get started by itself, does constructor or inner function get called at the same time..?
Thanks in advance plz someone shed light on this.
I think I figured it out.
So the update method actually calls itself recursively in a fairly roundabout way.
At the end up update you have these statements
if (!this.crashed) {
this.tRex.update(deltaTime);
this.raq();
}
The magic happens with the raq method. It's what calls the update method again. requestAnimationFrame is a browser method that requests a reanimation of the screen with the callback being called before the animation is done. Therefore, the update method is called again, which lets it call raq again which calls update again, etc...
raq: function() {
if (!this.drawPending) {
this.drawPending = true;
this.raqId = requestAnimationFrame(this.update.bind(this));
}
},
For reference: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
On how the application actually starts, I think it has to do with annotations and the closure compiler. The #export annotation on Runner means that an instance of it is getting created by the Self Invoker Function.
Then the constructor calls loadImages which calls init which calls update

Firebase-javascript API get data-nodes satisfying a condition in one trigger only. Also does the makes new TCP connection for each query?

There is a similar question here. However its related to REST and I want to ask regarding javascript-API . Also my case is bit different. So maybe someone can suggest some other solution.
I want to perform a query similar to this:
"SELECT * FROM db.table WHERE field1 ="val1";"
With firebase we can do following:
var ref = new Firebase("https://db.firebaseio.com/table");
ref.orderByChild("field1").equalTo("val1").on("value", function(record) {
console.log(record.val())
});
So firebase triggers my callback function for each child that satisfies field1="val1". Does it opens new TCP connection for each of these chlid queries? Also is there any way to get all the childs satisfying the condition just in one go(That is one callback is triggered when all of them are downloaded at the client).
So firebase triggers my callback function for each child that satisfies field1="val1"
Not exactly. It triggers the callback function exactly once, passing all the matching nodes in the DataSnapshot parameter. You can loop over them with:
var ref = new Firebase("https://db.firebaseio.com/table");
ref.orderByChild("field1").equalTo("val1").on("value", function(snapshot) {
snapshot.forEach(function(record) {
console.log(record.val())
});
});
The loop is needed, even if there's only one child. You can use snapshot.numChildren() to determine if there are any nodes matching your query.
Does it opens new TCP connection for each of these chlid queries
Nope. The Firebase client establishes a WebSocket connection when you first call new Firebase(...). After that all communication goes over that WebSocket. Only when the environment doesn't support WebSockets, does Firebase fall back to HTTP long-polling. Have a look in the network tab of your browser's debugger to see what's going over the wire. It's quite educational.
Also is there any way to get all the childs satisfying the condition just in one go(That is one callback is triggered when all of them are downloaded at the client).
I think I answered that one already.
Update based on the comments
Are the callback functions passed to forEach called synchronously?
Yes

javascript publish subscribe with callback

Scenario :- a json with checked & unchecked item count needs to be sent to a common function which in turn does some basic validation or shows error. There are different function each handle by different css/js team which call this function & depending on the common function result (true/false) each team/module that provided the json with check/uncheck status does the relevant action. Thus both common function (say getcount) & every independent team calling this function rely on the result of common function manipulate the dom/css independently & the common function too manipulate dom independently.
Instead of conventional way of calling function (say getCount({"chk" : 2 , "unchk" : 4})) i am looking for pusblish/subcribe method which is more cleaner as in Jquery & easy to convey to all as only topic name & contract/json needs to describe (also less if/else clause). Since common function is subscriber & when every independent function publishes the resultant chk/unchek json the common function can easily do the manipulation using the publish/subscribe approach but the independent method has to do counter action as well which is only possible if subscribe function can send the result. I know javascript is asynchronous also i understand that common method can publish (say "resultOfGetCount") which every independent function/module can listen to & do the action but is there any way in either in plain javascript or jquery where in on which subscriber can send the publisher the result in a way similar to $.ajax where in the callback function is called once server call is complete.
Looking for the best approach for such scenario.
Here's a simple publish subscribe model in jQuery from this blog post
var exampleHandle = function(){
//do stuff when topic is published
...
}
function subscribe(topic,handle){
$("#subscription").bind(topic,handle);
}
function publish(topic,params){
$("#subscription").trigger(topic,params)
}
function unsubscribe(topic,handle){
$("#subscription").unbind(topic,handle);
}
where you can use a simple string as a topic to subscribe or unsubscribe to the topic, and attach the handle as a callback function. The handle can also be used to unsubscribe from the topic later if necessary.
The method is based on jQuery’s trigger and bind functions. These
allow you to listen for a custom event on an element, and manually
trigger an event on an element. This provides the basic backbone for
the simple subscription model.
If an application element wants to
subscribe to a topic, they bind a handler to the “subscription
element”. This can be a designated element on the page, or just the
window element. You can also of course use different elements for
different subscriptions. Then, when something publishes to that topic,
the handler function will execute.
For publishing, a function can pass
a topic and parameters to the publish function. This calls jQuery’s
trigger to set off the event topic, passing along the parameters.
These params are passed to the handle function.
If an element wants to
cancel its subscription, they can pass the topic and handle function
to the unsubscribe method. Note that the handle has to be the same
function object that was used to originally subscribe, not a copy or
similar function. You also can use jQuery’s unbind to cancel all
subscriptions to a topic by only specifying the topic without the
handle function.

Categories