With
var twitPost = Meteor._wrapAsync(twit.post.bind(twit));
function process(screen_name)
{
twitGet('users/show', {'screen_name': screen_name});
}
a synchronous call to process("screen_name") works fine, but
stream.on('tweet', function(tweet)
{
process(tweet.user.screen_name);
});
yields Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
Any ideas how/if I could make this work? I would like to go via some processing function that can do other stuff except call twitPost.
As it is written, methods that use Meteor code (particularly ones that access Collections) need to be wrapped with a Fiber. One way to do so is to use Meteor.bindEnvironment:
stream.on('tweet', Meteor.bindEnvironment(function(tweet) {
process(tweet.user.screen_name);
}));
Related
I'm making a Chrome app that involves connecting to several BLE peripherals and sending write messages simultaneously to them. I need to know when each write operation has finished on which peripheral so I can initiate more operations for that peripheral, but there doesn't seem to be a way to reference the peripheral from the callback function. The callback function is passed as a parameter to the Bluetooth API write function:
chrome.bluetoothLowEnergy.writeCharacteristicValue(string characteristicId, ArrayBuffer value, function callback)
The API shows that the READ callback function has a characteristic parameter:
function(Characteristic result) {...};
And I've then been using result.service.deviceAddress to find which device the callback is for. But the WRITE callback does not have parameters.
This gives me no way to reference the peripheral that was written to, so I can't figure out which peripheral caused this write callback to run. I can see you could do this by having a unique callback function for each of a fixed number of devices, but could someone elaborate on how to do this more dynamically using a single callback function?
I ended up adding a shared function for the callbacks (d is a Device instance):
var writeCallback = function (d) {
//...
}
Then, in my object that keeps track of the device, I added a property for a call to this function using this:
class Device {
constructor(device) {
//...
this.writeCallbackLink = (function () {
writeCallback(this);
}).bind(this);
}
}
The bind(this) is vital to make sure that this refers to the actual object and not the runtime context. Then, when I call the API function, I use the callback link:
chrome.bluetoothLowEnergy.writeCharacteristicValue(d.write.instanceId,
data_buffer, d.writeCallbackLink);
This causes writeCallback to run with the d that triggered it as a parameter.
Reworded:
A common pattern is to pass callback functions, such as with Mongoose's save (just for example and simplified - no error handling):
someMethod(req:Request, res:Response){
document.save( function(err){ res.status(200).send({message: 'all good'})});
}
I'd like to externalize the callback. You can do this this way:
var respond = function(err:any, res:Response){
res.status(200).send({message: 'all good'});
}
someMethod(req:Request, res:Response){
document.save( function(err){ respond(err, res)});
}
...but ideally I'd like to do this by just passing a function like respond without having to create a call back function to enclose respond. I wanted to know if this is possible. Since the anonymous function has access to res, I thought there might be some way to gain access to res in a function defined externally. It appears there is not a way to do this so I'll live with wrapping it.
My original question was trying to isolate the specific issue I was interested in - which is to gain access to the caller's variables implicitly. Doesn't seem like that is possible. Fair enough.
Original Question:
I'd like to externalize a bit of code I use frequently and I'm having trouble understanding closure in the context of a Typescript method. Take a look:
var test = function(){
console.log("Testing external: "+JSON.stringify(this.req.body));
}
class Handler {
static post(req: Request, res: Response){
(function(){
console.log("TESTING anon: "+JSON.stringify(req.body));
}) ();
test();
}
}
Besides the fact that this does nothing useful, in this bit of code, the inline anonymous function has access to the req object, but the test() function does not. this in test is undefined. Removing this to match the inline function doesn't help.
I believe if I were to bind on this for the call I'd just end up with a reference to the Handler class when I really want to bind on the post method.
My motivation for doing this is that I want to make a function that can be passed as a callback to a bunch of different request handlers. When I write the functions inline it all works, but when I externalize it I can't get a closure over the variables in the enclosing method. I've read "You Don't Know JS: this & Object Prototypes", and in pure Javascript I can manage to make these sorts of things work but I'm obviously doing something wrong here (it may not be Typescript related, maybe I'm just messing it up).
So bottomline - is there a way I can externalize the handler and get access to the method variables as if I were writing it inline? I could just create an inline anonymous function as the callback that calls the external function with all the variables I need, but I want to really understand what is happening here.
This is not an answer, but will hopefully give me enough feedback to give you one because its not at all clear what you're actually trying to accomplish here and whether or not you actually understand what the terms mean is an open question since you use them correctly one minute and sketchily the next.
var test = function(){
console.log("Testing external: " + JSON.stringify(this.req.body));
}
In strict mode this will throw an error, in sloppy it will try to access the req property of the global object which is not likely what you want.
(function(){
console.log("TESTING anon: "+JSON.stringify(req.body));
}) ();
The IFFE wrapper is completely unnecessary, it literally adds nothing to the party. So why include it?
static post(req: Request, res: Response){
console.log("TESTING anon: "+JSON.stringify(req.body));
test(); // is this the spot where you are 'in-lining?'
}
What I think you want is this:
var test = function(reqBody) {
console.log("Testing external: " + JSON.stringify(reqBody));
};
class Handler {
static post(req: Request, res: Response) {
test(req.body);
}
}
I've got a very interesting issue in my Meteor js app: when I call a meteor method inside of my template's onCreated method the callback for that method call sometimes returns immediately with undefined as the result. It turns out that this is because the template got created as a result of running a meteor method simulation.
Two questions:
Is is this a bug? It certainly isn't the behavior that I expected.
How can I work around this without using weird hacks like setTimeout (and, by the way Meteor.setTimeout isn't allowed inside of method simulations)?
Some Code:
// My Template (Not my real code, just to demonstrate)
Template.saying.onCreated(() => {
var tmpl = Template.instance();
tmpl.saying = new ReactiveVar();
Meteor.call('getSaying', (err, saying) => {
// If called inside of a simulation, saying is null
tmpl.saying.set(saying);
});
});
// Assume that the above template is used in an {{each}} block
// and somewhere in my code I call this
Items.insert({});
// Because Items.insert wraps a meteor method which also runs as a
// simulation on the client, then the Template.saying.onCreated
// callback will be called in the context of an active simulation,
// which means that 'getSaying' method call will return immediately
// with undefined as the result.
Two possibilities to avoid simulation:
Define the method in a server side only file
Use isClient. When the simulation is run it will evaluate to true
if (Meteor.isClient) {
// on the client, the return value of a stub is ignored
return;
}
I have a NodeJS application and I want to execute some method for file validations but just one time (this method will validate some files under the node application).
Is there an elegant way to do this? Events?
The NodeJS documentation on modules states that:
Modules are cached after the first time they are loaded.
which you can take advantage of by adding static code to the module. Regardless of how many times the module is loaded, the static code will retain its state(/value).
You can use that state from a method to implement a method that can be called whenever you like -- at the best time during initialization -- but only ever be called once. This is pretty simple:
var called = false;
function checkFiles() {
if (called) return;
// Perform your validation
called = true;
}
module.exports = {
checkFiles: checkFiles
};
Because of the module caching, you can require this file in as many places as you need and it will still only execute once.
To invoke this function, you have a few options:
For a simple application, you can call the function from your main module (or function) and it will be invoked at that time. If the validation should be asynchronous, you can wrap your main method in a function and pass that to the validator as a callback.
//#! /bin/env node
var express = require('express');
var validator = require('./validator');
validator.checkFiles();
var app = express();
var server = app.listen(3000, function () {
...
});
For a more complicated application, you should call this function during your existing initialization routine (again, using callbacks as necessary).
If you have a nice modern promise-based initializer, you could simply add the validator as the first step of the chain.
I'm trying to build an API in JS that will perform some operations and then execute the callback that's registered in AS when it's done. Because it's an API, I am just providing a JS method signature for another developer to call in Flash. Thus, the callback name that's registered in the AS part of the code should be a parameter that's passed in to the JS API in order for JS to communicate back to Flash.
For example:
[AS3 code]
ExternalInterface.addCallback("flashCallbackName", processRequest);
ExternalInterface.call("namespace.jsFnToCall", flashCallbackName);
function processRequest(data:String):void
{
//do stuff
}
[JS code]
var namespace =
{
jsFnToCall: function(callback)
{
//Do stuff in this function and then fire the callback when done.
//getFlashMovie is just a util function that grabs the
//Flash element via the DOM; assume "flash_id"'s a global var
//Below does not work...it's what I'd be ideally be doing some how.
getFlashMovie(flash_id).callback(data);
}
};
Because the definition of the function is in AS, I can't use the window[function name] approach. The only way I can think of is to build the callback in a string and then use the eval() to execute it.
Suggestions? T.I.A.
Well, I can think of one thing I would try, and one thing that would work.
What I would try first.
getFlashMovie(flash_id)['callback'](data);
What would work: Have the callback always be the same, say callback. The first parameter to the callback could be used to determine what actual function to call in flash. For example:
function callback($fn:String, $data:*) {
// either
this[$fn]($data);
// or
switch ($fn) {
case "callback1":
DoSomeCallback($data);
break;
}
Additionally passing the objectID makes it a bit simpler:
ExternalInterface.addCallback("flashCallbackName", processRequest);
ExternalInterface.call("namespace.jsFnToCall", ExternalInterface.objectID, "flashCallbackName");
Then in your JS:
var namespace =
{
jsFnToCall: function(objectID, callback)
{
//Do stuff in this function and then fire the callback when done.
document[objectID][callback](data);
}
};