How can you tell if you're within a method call in Meteor? - meteor

I have this setup where when collection.update() is called from the client, a before-update hook gets triggered in the server (using matb33:meteor-collection-hooks). This trigger then uses Meteor.user().someData to get some data off the user. This works fine.
The problem is sometimes I need to update from the server, with no user in context. So I get a Meteor.userId can only be invoked in method calls error.
I'd like to know how to properly detect if the update hook is being run outside the context of a method call or publish function, when there is no user.

Related

With Meteor, how to I run a singleton that updates periodically while clients are connected?

I'm just getting started with Meteor and I have a REST API hooked up with publish / subscribe that can periodically update per client. How do I run this behavior once globally and only refresh as long as a client is connected?
My first use case is periodically refreshing content while clients are active. My second use case is having some kind of global lock to make sure a task is only happening once at a time. I'm trying to use Meteor to make a deployment UI and I only want 1 deployment to happen at once.
publish/subscribe will work automatically only when clients are connected. However, do not put any functionality that you want to control amount of execution times in publish or subscribe functions. They might run arbitrary amount of times.
If you want some command to be executed by any client use Meteor.methodss on server side, and call it explicitly with Meteor.call from client template event.
To make sure that only one deployment happens at any given time, simplest way would be to create another collection, called for example, CurrentDeployments.And any time deployment script function in Meteor.methods is executed, check with CurrentDeployments.findOne if there are ongoing deployment or not, and only call new one if none is running.
As a side bonus, subscribe to CurrentDeployments in client, to disable 'deploy' button in case one is already running.

Do local db writes happen synchronously or asynchronously?

New to firebase and trying to understand how things work. I have an android app and plan to use the offline support and I'm trying to figure out whether or not I need to use callbacks. When I make a call like:
productNode.child("price").setValue(product.price)
Does that call to setValue happen synchronously on the main thread and the sync to the cloud happens asynchronously? Or does both execute asynchronously on a background thread?
The Firebase client immediately updates its local copy of the data with the new value. As part of this it fires any local (value, child_*) events that are needed.
Sending of the data to the database happens on a separate thread. If you want to know when this has completed, you can register a CompletionListener.
If the server somehow cannot complete the write operation (typically because the write violates a security rule), the client will fire any additional events that are needed to get the app back into the correct state. So in the case of a value listener it will then fire a second value event with the previous value.

HotTowel (Durandal really) and SignalR initialisation

So I'm integrating SignalR and HotTowel, although really I think this is a matter of how to integrate with Durandal itself.
The issue is I have obviously multiple views. Some of these views I want to respond to SignalR messages. The question is how to do this integration considering that SignalR events have to be started before I call SignalR's hub start method.
So take the example I have view1 and view2. I want each to do something when a SignalR message is received and in the context of that view (so let's say update the DOM somehow). It's an SPA obviously so calling the SignalR start method for each view seems like a bad idea, so starting SignalR once at boot sounds like the right plan, but at that point my views may not have been loaded, and still how would I ensure that my events have the right context for the page.
This is based on my understanding that all events for SignalR have to be registered before I call start. Any thoughts clever people of StackOverflow?
Edit to expand on the problem
Part of the website involves uploading files for parsing and processing to import into a database. I have created a view where the file is selected and uploaded (using FineUploader) to a WebApiController. The controller does the basic steps of checking the uploaded file and then starts an async task to actually do the parsing and processing, while immediately returning the basic "Yep that uploaded fine" message.
This causes the list of 'in progress' files to refresh and the file appears with an 'Uploaded' status. As the async task occurs, the file is parsed, then processed against a rules system, and then finally imported into another back end data store. As each of these status changes occur, SignalR sends messages to the client to notify them of these changes, and thus update the status against the filename. In order for this to occur I must attach a function to the event as it received in SignalR. That even needs some kind of reference to my view (actually viewmodel) so it can update the correct value.
As SignalR should be started once with a call to hub.Start(), I am trying to do it during the 'boot' phase. However when my SPA starts, that view has not been loaded, and therefore neither has that viewmodel, and therefore my function that is responsible for initialising SignalR can have no understanding of the view/viewmodel it must update.
Examples I've seen on using SignalR show it being used in one view, but that doesn't really work surely if you need it in multiple views (you can't just keep calling hub.start() can you)?
Sorry, if this still doesn't make sense I'll post some code or something.
If you use
$.connection.myHub.on("myMethod", function (/* ... */) { /* ... */ });
instead of
$.connection.myHub.client.myMethod = function (/* ... */) { /* ... */ };
you can add client-side hub methods after calling $.connection.hub.start();

Where should Meteor.methods() be defined?

http://docs.meteor.com/#meteor_methods
I have tried it in publish.js in my server folder.
I am successfully calling Meteor.apply and attempting the server call from the client. I always get an undefined response.
Calling Meteor.methods on the server is correct. That will define remote methods that run in the privileged environment and return results to the client. To return a normal result, just call return from your method function with some JSON value. To signal an error, throw a Meteor.Error.
On the client, Meteor.apply always returns undefined, because the method call is asynchronous. If you want the return value of the method, the last argument to apply should be a callback, which will be passed two arguments: error and result, in the typical async callback style.
Is your server code actually getting called? You can check that by updating the DB in the method and seeing if the client's cache gets the new data, or calling console.log from inside the method body and looking at the output of the "meteor" process in your terminal.
There are several places I can define my Meteor.methods() (with pro's and con's):
On the server only - when the client calls the method, it'll have to wait for the server to respond before anything changes on the client-side
On the server, and uses a stub on the client - when the client calls the method, it will execute the stub method on the client-side, which can quickly return a (predicted) response. When the server comes back with the 'actual' response, it will replace the response generated by the stub and update other elements according.
The same method on both client and server - commonly used for methods dealing with collections, where the method is actually a stub on the client-side, but this stub is the same as the server-side function, and uses the client's cached collections instead of the server's. So it will still appear to update instantly, like the stub, but I guess it's a bit more accurate in its guessing.
I've uploaded a short example here, should you need a working example of this: https://gist.github.com/2387816
I hope some will find use of this addition, and this doesn't cloud the issue that methods are primarily intended to run on the server as debergalis has explained.
Using Meteor.methods() on the client is useful too. (look for "stub" in the Meteor.call() section too...)
This allows the client to (synchronously) simulate the expected effect of the server call.
As mentioned in the docs:
You use methods all the time, because the database mutators (insert,
update, remove) are implemented as methods. (...)
A separate section explaining use of stubs on the client might ease the understanding of methods calls on the server.

How to kill a javascript async call to a .net webservice?

My javascript code is calling a asp.net webservice, so i have a call to the webservice something like this:
MyWebservice.GetData(param, ResponseReceived, ResponseTimeOut, ResponseError);
When the webservice returns data, ResponseReceived method is called.
However sometimes the user might navigate to another url before the webservice call actually returns, in such a scenario FireFox throws an Error saying 'An error occured oricessubg the request. The server method GetData failed'
So my question is how can i kill the async call when the user navigates to another page or makes another request to the webservice? I know in a normal XMLHttpRequest i could have called Abort method, but not sure how to make it work with the above webservice proxy.
A good practice would be to keep your common functions in a common place, which is accessible from all of your pages.
This would include the OnError function. That way you can safely reference that same function from all of your pages. If you need to provide custom Error Functionality, you can either override this function on your page, or include a handler in your common function, and call if it was assigned.
A good place to put such common function would be inside a root master page, or a shared JavaScript file referenced from root master page.
What is good about this, is that hopefully your OnError function does some logging, so you can get an idea of what fails and how often so that you can design your app accordingly.
Ok I figured out a solution, I can call get_executor() method to get an instance of the XmlHttpExecutor class, on which I can call the abort method. Hope it helps others facing a similar problem.
I'm still eager to find out other solutions.

Resources