Meteor as AJAX application (not reactive)

We would like to implement a application as simple as simmilar to AJAX application using Meteor, and we don’t need real time (non-reactive) sync of data with clients.

After some research, we found following approach similar to AJAX (or RPC).

Client functions will invoke back-end (remote) methods to get data, and returned JSON data will be put into ReactiveDict to make it available for template helper functions.

Please suggest / help if there is better approach.

May I ask why?

I achieved something similar by fetching my result sets manually to prevent any reactivity. Kept me from having to manually build services for something Collections can handle easily.

edit You can also just pass {reactive:false} to find.

@Sparser How did you get your data into client side collections (minimongo) without using pub/sub? That’s what I’m interested in.

I imagine it’s something pretty simple once you know how to do it – it’s just not something I’ve done yet (and I can see it being useful sometimes).

Well, you could use Asteroid or you could just stop the subscription after you’ve gotten your initial data sets.

Another option would be to use pub/sub but don’t bind it to anything, just monitor the collections for changes and then have clientside logic run rather than reactivity.

If I’m not missing the point of the question;

Call a meteor method which returns the resultset. And in your callback where you called the method, assign the value to a variable from which you create a view.

Or better yet you can use https://atmospherejs.com/simple/reactive-method to directly get the result of a method call and assign to a template helper.

If the method itself does not expose a reactive data source, then this is essentially non-reactive and conformant to the meteor way of things, rather than manual ajax calls.

Yeah but that is going to be a ton of work to map everything back to Methods.

AJAX as a goal is such a strange request. May I ask why you want to do this @sambapotla?

Well, you could run Minimongo in the browser and then manually run Inserts off whatever dataset you want to upload to it.

The problem would be making sure those inserts don’t get sent back to the server. You’d have to use a custom implementation of Minimongo rather than Meteor’s. Which is where Asteroid comes into play. You use that to decouple your app from the Meteor server.

From what I gather, @sambapotla needs to query external apis as datasources and does not want to do extra work to make them reactive.

I don’t understand this reasoning. We’ve integrated plenty of external apis using traditional Meteor Collections and Methods to bridge the external calls. Why remove reactivity for the native functionality just because your external services need to be manually polled/queried on demand?

Well, I am pro reactivity, but I also can agree that there are times reactivity is not wanted.

One reason would be UX, where you don’t want the current UI to change until after you want it to.

Another reason would be static data sources, or sources where you know will not change often, and performance is a big concern, so much so that introducing collections and pub/sub where they are not necessary may be bad. And is extra work.

So in essence I’m not looking at this as removing reactivity. I see it as adding it when it is necessary.

I may live with querying facebook for a user’s latest posts on demand rather than polling it every T seconds and loading them onto a collection or a custom reactive data source for reactively displaying on the client.

Yep, that makes sense to me, and we actually did the exact thing in my most recent application.

We put a toggle in that disables reactivity on click. If the value evaluates to false, then the Cursor is returned by the Template Helper as-is. If it evaluates to true, we call the Cursor’s .fetch() method and then return that to the Template.

Since fetch returns a simple array, there’s no reactivity to kill and we didn’t have to change any other logic. The only catch is we have to manually refresh the array when the need arises.

1 Like

@sparser that’s really interesting. Was that an internal business app? How did you explain your users what that toggle does ?

In fact I’m doing that as well, chaining an extra fetch to the find to kill reactivity, but that’s so far been my decision as a developer. It never occured to me that I could actually mold that into a feature.

@Sparser - Thanks for replying. @serkandurusoy has added few reasons why we want to avoid reactivity. App mostly display static data and the screen update is driven by user actions.

And other reason : We cannot load MongoDB with polling queries or also no single oplog, as we use sharded MongoDB with few TB of data.

Yeah it is. We didn’t do much, to be honest. We left reactivity on by default and made sure the toggle was visible and clearly labeled.

Only my, ahem, older stakeholder even wanted it in place.

1 Like

I might ask why you’re going with Meteor.js then. A more traditional MEAN stack might make more sense?

If you’re staying, Methods make the most sense for this.

Yes, external sharded MongoDB datasource. And no extra work of polling queries / no oplog.

To avoid most of housekeeping efforts required for device compatability / java script packaging / full stack environment and make developer env simple and easy.

You can also get the convenience factor from something like this

@Sparser
We have tried with Curser’s .fetch() to disable reactivity. Any updates to datasource not propogated to client. But still, Meteor is triggering queries to MongoDB.

You could try using fast-render to write the initial dataset, copy it into something persistent in the client layer, and then cancel the subscription by calling “stop” on the subscription object.