Unsubscribe from publication in meteor app - meteor

I was wondering if there is a proper way to stop client's subscriptions.
For example, i have 2 pages, on the first i subscribe the client to users publication, and on the second i subscribe to projects publication.
When the client goes from users page to the projects page, he is still subscribed to the users, although he does not need it on projects page.
So my first question is: Does it take memory or CPU? When the client is subscribing to more and more publications, when he goes from route to route.
And the second: What is the proper way to unsubscribe??
For example when he goes to projects page, unsubscribe from the users publication.
Some packages i see does that. For example reactive-table.
Thank you in advance!

Generally if you want to stop subscriptions you do it with Meteor.stop(). From the guide, on how to stop subscriptions:
if you call Meteor.subscribe() conditionally inside a reactive context (such as an autorun, or getMeteorData in React) or via this.subscribe() in a Blaze component, then Meteor’s reactive system will automatically call this.stop() for you at the appropriate time.
So normally you don't have to stop subscriptions. It's done automatically.
-For your first question, yes, depending on the application it can be CPU intensive and this is why you want to avoid multiple pub/sub in chat applications, for example.
-For the second question, in your case what you need to do is template-level subscription and not router-level, in order to have the data you need only to the template you need. See this example to learn how you do it with Flow Router, and the same applies to other routers, as well.
Template.blogPost.onCreated(function() {
var self = this;
self.autorun(function() {
var postId = FlowRouter.getParam('postId');
self.subscribe('singlePost', postId);
});
});

Related

How to manage stateful reducers in Redux?

I'm starting to read up on Redux and I like what I see so far. There is one area of concern that I have and it's async actions. I've seen how sagas, thunk, and others help in this area but I feel like I'm missing something.
I'm a fan of using FSMs to handle application logic and prevent things from getting out of sync, so coming to redux and not seeing something like this is a bit jarring to me.
I have an example in my mind that I keep coming back to that I want redux (or some plugin) to solve:
I have a login form. When the user presses login, an async call is made to a server. This is fine. But if the user presses login again, then another call is made to the server and the application state is now out of sync. I could add a state property that defines loggingIn, but this only works in this example.
Lets say I have a much bigger dependency. Lets say when a user logs in, an action is done to preload some data. And that data contains a preflight of more data to load. This now introduces a lot of if/else conditional logic and adds more information to the state. In a FSM, I would define multiple concurrent states for theses. Such as user:loggedIn, manifest:fetched, pageData:fetched. And each state would be a child of each other: user:loggedIn -> manifest:fetched -> pageData:fetched. So if a request was made to login, or refetch data, an error would be thrown because it's not a valid handler for the current state. How does one accomplish such complexity in Redux? Is it even possible?
Another example. Stemming off the Reddit API example. Lets say a user goes to a reddit post. I don't want the user to be able to submit a comment on the post before it's even loaded. I know this could be handled on the UI side with conditionals and such, but that seems really archaic.
I really appreciate any guidance.
Thanks!

Are template-level subscriptions with multiple templates subscribing to the same publication run once or once for each template?

Suppose you have template1 and template2, both subscribing using this.subscribe('samePublication', sameArg) inside their .onCreated() and this.autorun().
What happens when we have something like this:
<template name="template3">
{{>template1}}
{{>template2}}
</template>
Will this.subscribe('samePublication', sameArg) run once for each template, and hit my server and DB twice?
Should I put this.subscribe() inside the .onCreated() on template3?
My own understanding is 'no' and 'no', after having read this: http://docs.meteor.com/#/full/meteor_subscribe
Hoping someone more knowledgeable can comment.
Thanks in advance.
In my experience, the subscriptions load and hit your DB every time you route to the view and render the template.
While the general best practice (probably to promote modularity) is to use template level subscriptions, I have found that if a route is heavily used and frequently changed to and it involves large amounts of docs, then it makes more performance sense to load those subscriptions on client startup and share between views.
Did you know you can pass an argument with a subscription to a publication and use the argument in your publication to filter the results? Using this often makes a big difference on the performance without falling back to global subscriptions.
PS: I am working on parallel subscriptions that do not start until after the loading of 'fast' landing pages, so that when the user switches to a heavily subscribed page, the parallel loading would already have completed, but would not affect the 'first impressions' of the user.

Subscribe, publish dynamic collection made in run time

I am trying to make a chat application in meteorJS and i was thinking of making a seperate collection for each groups dynamically when they initiate chat, I want to publish and subscribe that collection for transmitting chat information and all the group user can subscribe it, but i am not being able to create a collection dynamically.
I tried making a function which gets call when the user subscribe the collection.
this.createDb =(name) ->
#ChatDb = new Mongo.Collection(name)
return true
everything is fine, but when i subscribe this collection from client side, ChatDb is unknown, Can any one help me with this, that would be great. :)
ps- i am writing code in angular-meteor framework
Andrew Mao's answer to a similiar question:
In most instances, you probably don't want to create multiple
collections, but instead use one collection and send views of it to
clients depending on their subscription.
You may want to check out the
https://github.com/mizzao/meteor-partitioner package I've built which
is designed especially for this purpose, and includes an example for
how to do this for multiple chat rooms. You can also see
https://github.com/mizzao/CrowdMapper for an implemented example.
I haven't done Meteor for a while now so I couldn't give you a solid answer. But I remember quite clearly that creating collections dynamically is not the recommended way for achieving what you want to do.

clear client collection on route change

I've been struggling with the following issue in Meteor + iron router:
I have a page (route) that has a subscription to a mongo collection
on that page, I have some logic which relies on a cursor querying the collection, also utilizing an observeChanges handler (namely, I'm running a search on that collection)
the problem in this case is the collection is being preserved in the client throughout route changes, which causes 2 unwanted effects:
1) the collection isn't necessarily needed outside that route, meaning i'm wasting client RAM (the collection, or even a subset of it, is likely to be quite big)
2) whenever i go back to that route, I want to start off with an empty subset for the observeChanges handler to work properly.
Any advice on how to clear the mirrored collection? (using the Collection._collection.remove({}) hack is bad practice, and doesn't even solve the problem)
Thanks!
solved this by storing the subscription handles. used them to unsubscribe the data (i.e. subscription_handle.stop() ) on template.destroyed()

Best approach to wait untill all service calls returned values in Flex PureMVC

I am writing an Adobe AIR application using PureMVC.
Imagine that I have an page-based application view ( using ViewStack ), and user is navigating through this pages in some way ( like clicking the button or whatever ).
Now for example I have an Account Infromation page which when instantiated or showed again needs to load the data from WebService ( for example email, account balance and username ), and when the data is returned I want to show it on my Account Information page in the proper labels.
The problem is when I will execute this three Web Calls, each of them will return different resultEvent at different time. I am wondering what is the best way to get the information that ALL of the service calls returned results, so I know that I can finally show all the results at once ( and maybe before this happens play some loading screen ).
I really don't know much about PureMVC, but the as3commons-async library is great for managing async calls and should work just fine in any framework-setup
http://as3commons.org/as3-commons-async/
In your case, you could create 3 classes implementing IOperation or IAsyncCommand (depending on if you plan to execute the operations immediately or deferred) encapsulating your RPCs.
After that is done you simply create a new CompositeCommand and add the operations to its queue.
When all is done, CompositeCommand will fire an OperationEvent.COMPLETE
BTW, the library even includes some pre-implemented common Flex Operations, such as HTTPRequest, when you download the as3commons-asyc-flex package as well.
I would do it in this way:
Create a proxy for each of three information entities (EMailProxy, BalanceProxy, UsernameProxy);
Create a delegate class which handles the interaction with your WebService (something like "public class WSConnector implements IResponder{...}"), which is used by the proxies to call the end ws-methods;
Create a proxy which coordinates all the three results (CoordProxy);
Choose a mediator which will coordinate all the three calls (for example it could be done by your ApplicationMediator);
Create notification constants for all proxy results (GET_EMAIL_RESULT, GET_BALANCE_RESULT, GET_USERNAME_RESULT, COORD_RESULT);
Let the ApplicationMediator get all 4 notifications;
it is important that you should not only wait for all three results but also be ready for some errors and their interpretation. That is why a simple counter could be too weak.
The overall workflow could look like this:
The user initiates the process;
Some mediator gets an event from your GUI-component and sends a notification like DO_TRIPLECALL;
The ApplicationMediator catches this notification, drops the state of the CoordProxy and calls all 3 methods from your proxies (getEMail, getBalance, getUsername).
The responses are coming asynchronously. Each proxy gets its response from the delegate, changes its own data object and sends an appropriate notification.
The ApplicationMediator catches those notifications and changes the state of the CoordProxy. When all three responses are there (may be not all are successful) the CoordProxy sends a notification with the overall result.
I know it is not the best approach to do such an interaction through mediators. The initial idea was to use commands for all "business logic" decisions. But it can be too boring to create the bureaucracy.
I hope it can help you. I would be glad to know your solution and discuss it here.

Resources