Meteor routing params and database query - meteor

I am brand new to Meteor (just 2 days in and also new to Mongo and the whole stack), so please bear with me. I am laying out high level design patterns for an application at this point.
One of the things I will need to do is allow users to specify a URL (e.g. http://meteor.example.co/XXXXX2016) and then get the document from the database where one of the fields (that is not the ID) is equal to the XXXXX2016 part of the URL.
Based on what I think so far, one way way to deal with this seems to be:
1) Have the XXXXX2016 be a route parameter (most likely going to use Iron Router for routing)
2) Have the client query for that document (or is there a way to do this with pub/sub that is better?)
3) Update the templates with the data form that document (and eventually related and sub documents).
That parameter from the URL (or route) controls the banner logo for every sub-"page" along with many other things and is the catalyst of the entry point when within the app. Am I moving in the correct general direction or are there other approaches/considerations I should look into before moving forward?
I am not sure if this should more client or server oriented or how best to structure this sort of paradigm in Meteor.
I also know this could be considered somewhat of a broad, open ended question/answer. But I would like to hear any any feedback from more experienced Meteor peers if they are willing to share.
TIA!

Here's two ways:
Code in:
/lib runs on both client and server
/server runs only on server
/client runs only on client
Create DB Collection in /lib.
Iron Router reads the params from the URL for a particular route.
IR takes this param and does a DB subscription.
Write a corresponding Publish function in /server for this subscription.
In the template JS you can directly access the DB collection since the route is now subscribed to it.
OR
Create DB Collection in /lib.
Subscribe to DB Collection in Iron Router, which is in /lib.
Write a corresponding Publish function in /server for this subscription.
Iron Router reads the params from the URL for a particular path/route.
IR takes this param and does a DB query, bringing back either a cursor or array of objects.
IR sets the data context of the route using the info above.
In the template JS for your route you can then access the data and do functions with the data returned from Iron Router - just search around for how to use the route's data context in your template callbacks.

Related

How to properly mock API results for testing with NextJS and MSW?

First of all, if I should ask this question elsewhere please let me know, as I'm not sure where it belongs.
I have a working application with NextJS and MSW, where I can capture the server-side API requests with MSW and return mocked JSON results.
The issue I have is that there are probably about 15 API calls that I need to mock in order to test my application properly
While I could just call each one of these manually, copy and paste the results into a file and then just return that data from the file when I capture the API call, this not a very scalable solution, especially if the back-end API changes.
Question: What are your best methods for automating the generation of these results?
In the past I have created JSON files that have all of the URL paths and query parameters explicitely listed, and I would parse through this file and query every endpoint, and then I had template files which would be used to re-populate my fixtures directory with all of the mocked responses, however this was also very cumbersome.
(For reference, the API has a somewhat similar structure to this one: https://api.gouv.fr/documentation/api-geo, where there are multiple endpoints for fetching data, and each endpoint supports a number of different query parameters to tweak the call.)

Grails 4 Async with Database Operations

My Grails 4.0.10 app needs to call an external service. The call may take up to 3 minutes, so it has to be async'ed. After reading the doco I wrote a non-blocking service method to perform the call using a Promise without too much trouble.
The documentation describes how async outcome can be displayed.
In my case the outcome affects the database. I must create new domain objects, modify existing domain objects and persist the result in the onComplete closure. The doco is rather quiet on how to do this.
These are my assumptions about the onComplete closure. My question is: Are the assumptions valid? Is this the proper way to do it?
No injected stuff is available, neither services nor (for example) log -- things you normally expect in a service
Database logic must be enclosed first within Tenants.withId if multitenancy is used, and then within withTransaction
withTransaction is prefixed with a domain name. However, other domains may freely be manipulated and persisted in the same closure
Domain instances picked up before the async call may be attached to the current session like this instance.attach() and then modified and saved
If logging is needed, create a new log instance

Meteor subscribing to the same publication on different routes, are cursors re-run for each route?

When two routes within a meteor application subscribe to the same publication, are the cursors within the publication re-run when the user switches between these routes?
If so, How can I prevent this because it is unnecessary.
As this publication is in high usage across the app on most routes, is it worth subscribing from the app body (globally)?
Are you using iron:router?
You can use something like:
Router.configure({
waitOn: function() { return Meteor.subscribe('sub'); }
})
This is one technique for a global publication.
It doesn't re publish if your routes are subscribing to the same publisher.
by adding subscription management to your client you can make sure that client's browser will keep the data for a period of time so if user came back to the page or another route needs the subscription, the app don't need to get the same data again.

Symfony 2 - How can I share data between controllers

I need to be able to make some request data from one controller available in another controller. I can make a service to set the data in one controller, but when the other controller fires and I get the service, a new instance of the service is created. Is there any way I can make this data static and share it between two controllers?
The same basic things you would do whenever you need information to be available in PHP from a new request:
Store it in the session. Symfony2 has a great session component for this. Ideal for fleeting data that needs to be saved only while the user is navigating
Store it in the database. Symfony2 supports Doctrine which makes this very easy. Ideal for permanent storage
Optionally:
Store it on the filesystem. Not recommended unless it's actually a file, but possible as well.
In the end, rather than using the session to store data, I created two separate routes to the same controller action. I added an optional argument in the controller action, with a default value only specified in one of the routes. I can then test for that argument's value when the controller runs. In the Twig template that calls this controller action, the path can be generated using either one of these routes, depending on a variable already available.
Bit of a work around, but problem solved!

Meteor: are code inside Meteor.isServer block readable from client?

I am confused as to when you would use the isServer block to put stuff in. obviously, database calls and etc. Does this show up in the client browser?
I would advise against using that instead put your stuff in folders as advised on the unofficial meteor faq
Even if you use if (Meteor.isServer) {...} this block will still be sent down to the client if you don't use the folder structure above i.e putting it in /server. But it will ignore all the code inside it.
On the server side code you would place code you only want to run on the server, i.e Publish functions, and data that would be more sensitive & the user shouldn't have access to.
I think it does get sent down to the client, unless it's in the server folder. In response to one of the comments about sharing global variables, I've been using this pattern. Create the same global variable in client and server folders respectively, and once outside of those folders for any shared code. Initialize the global variable in each place by testing to see if it already exists.
MyVar = typeof MyVar === 'undefined' ? {} : MyVar;
Then, just put methods where you need them. For instance, I'll have a User object with a method that tests to see if the user is authorized. I'll declare the method once on the server global User, and once on the client global User. The methods are different because the server version checks for custom properties on the user object which aren't available on the client. Then, in a Meteor.methods method, which runs on both the client and server, you can invoke the authorization method, and it will call different methods depending on if it's running on the client or server.
I was asking myself the same question today and stumbled upon this package:
https://github.com/mquandalle/meteor-minifiers
It seems like Meteor does not remove the Meteor.isServer Blocks by default.
See this discussion:
https://groups.google.com/forum/#!topic/meteor-talk/iHat47f6iGE
I haven't used it as of now, but it looks promising.
If you do not want to use an extra package, I'd recommend to use the client and server folders. Only the files in the client folder are sent to the client.

Resources