Meteor Package - Iron:router - How to prevent my package routes to execute the hooks of the apps that use it? - meteor

I am creating a meteor package using iron:router, it works great.
The routes logic of this package is very specific.
But as soon as I add this package in a Meteor app that is also using iron:router, the hooks defined by the Meteor app (onBeforeAction, onAfterAction, ...) are called for the routes created by the package.
I'd like to prevent my package routes to execute the hooks of the app.
Is there a simple piece of code I could use to isolate the routes of my package from the "external" hooks? Maybe I could create a specific RouteController?
The last option for me is to implement a router from scratch...
Thank you!

The code that solved my issue is the following:
let MyRouter = new Iron.Router;
MyRouter.onBeforeAction(Iron.Router.bodyParser.json());
MyRouter.onBeforeAction(Iron.Router.bodyParser.urlencoded({extended: false}));
The solution is to declare a new isolated router. The 2 lines under the router declaration enable to retrieve the data of POST requests.

Yes, you need to create isolated controller:
var MyPackageController = RouteController.extend({
onBeforeAction: function () { ... },
onAfterAction: function () { ... }
/* other options */
});
Router.map(function () {
this.route('packageRoute', {
controller: MyPackageController
/* other options */
});
});

Related

iron:router doesn't work after updating meteor

I recently updated my meteor project and whenever i try to run my project i got this :
Router.route('/', function () {
this.render('Home', {
data: function () { return Items.findOne({_id: this.params._id}); }
});
});
this is my route that should direct the user to "main" template
Router.route('/', {
template: 'main'
});
i used to get similar problem when i first added iron:router package, and the reason was because i haven't implemented it. I believe the way i should implement it is different after the update. please correct me if am wrong
Your router file needs to be included above or in a folder above your client and server folders. It's just there, if router is not contained above client and server than meteor does not digest it properly for the function it serves.
Short answer:
Put router.js where-ever it is that you start your meteor application.
(as opposed to .\client or .\server)
How you configure main template:
Router.configure({
layoutTemplate:'yourMainTemplateName' //main template should have {{> yield}} inside HTML which tells iron:router where to render templates per route
});
Route configuration:
Router.route('/', function () {
this.render('homeTemplateName');
});
Update your question with your new codes if it doesn't work.

MeteorJS with spiderable - or another solution for making App crawlable?

Current we are using a meteor App with the iron:router package and also the spiderable and phantomjs for making this app crawlable by google.
In our special case we have some Routes where we call Meteor methods which are running async before we render the right template into our layout.
When testing spiderable on these routes the template will never get rendered and instead our "loading" template will be the rendered template.
We are testing this with /?_escaped_fragment_=
Now we are looking for a solution to tell spiderable that the page is ready or is not ready so we can control when the page has to be rendered.
Router.route('/awesome-route', function(){
// This is how it could look to tell spiderable that it has to wait
Spiderable.pleaseWait();
// Render the loading template until our route is ready
this.render('loading');
// Waiting for the response of our method
Meteor.call('data', function(err, resp){
this.render('awesome', {
data : resp
});
// This is how it could look to tell spiderable we are ready / always be polite
Spiderable.thanksForWaiting_WeAreReady();
});
}, {
name : 'awesome'
});
When opening now localhost:3000/awesome-route?_escaped_fragment_= we will just see the laoding template ...
The other option for us would be: Is there any alternatives for getting meteor apps crawled by google yet ?
Since spiderable will pre-render your template using phantomjs on server, there is no need for special methods like spiderablePleaseWaitForALittleBitMore_Please
You can just say to your iron:router that template is not rendered yet. Use onBeforeAction hook:
Router.route('/awesome-route', {
name : 'awesome',
template: "awesome",
loadingTemplate: "loading",
onBeforeAction: function(){
var next = this.next;
Meteor.call('data', function(err, resp){
next();
});
}
});

Meteor - How to load a JS library for only specific users?

I'm designing an administration interface with graphics and so on and I'm using the Highcharts Library (140kb). I want this file to be loaded only for admin users. What would be the best way to do it?
I just saw that we could use Iron-Router to conditionally load JavaScript but I don't like the idea to handle this kind of things inside the router as below:
Router.map ->
#route 'admin',
path: '/admin'
template: 'admin'
action: ->
$.getScript '/js/moment.min.js', (data, textStatus, jqxhr) ->
if jqxhr.status is 200
#render()
NOTE: I wrote a little blog post to load a library for only specific users with Meteor.
Does this not work (on the client)?
var loaded = false;
Deps.autorun(function() {
if (!loaded && isAdmin(Meteor.userId())) {
$.getScript("/js/moment.min.js");
loaded = true;
}
});

How can I access the name of the current route in meteor when using meteor-router?

I'm building an app using meteor and meteor router, and I would like to make a template helper for checking if the route is a specific one ({{#ifRouteIs login}}{{/ifRouteIs}}).
I had the same issue. Building on your answer, I found a working solution. It needs to go in the client side of Meteor.
Handlebars.registerHelper('ifRouteIs', function (routeName, options) {
if (Meteor.Router.page() === routeName) {
return options.fn(this);
}
return options.inverse(this);
});
According to meteor-router's README, you can get the current page with Meteor.Router.page(), so the helper might look like this:
Handlebars.registerHelper('ifRouteIs', function (routeName) {
return Meteor.Router.page() === routeName;
});

How to debug template in Meteor/handlebars?

According to this blog post, I should register a helper to better debug handlebars templates, but is not working:
ReferenceError: Handlebars is not defined
So, how can I {{debug}} in Meteor/handlebars?
This is the helper function I use for debugging in my own projects:
Template.registerHelper("debug", function(optionalValue) {
console.log("Current Context");
console.log("====================");
console.log(this);
if (optionalValue) {
console.log("Value");
console.log("====================");
console.log(optionalValue);
}
});
You can then call it in your templates with {{debug}} and it displays the context you are currently in. Read more at http://docs.meteor.com/#/full/template_registerhelper.
In Meteor 0.4.0 you register handlers like this:
Template.myTemplate.helpers({
helper: function () {
// some code here
console.log(arguments);
}
});
There is no need to call Handlebars directly.
Make sure that you register your helper in client (or shared) meteor code.
Handlebars.registerHelper('helper', function() {
// Do stuff
});
This should be callable via {{helper}} in your templates.
For the sake of completeness: you can also use
Template.registerHelper('helper', helperFunc);
instead of Handlebars.regsterHelper('h',f);
A small reason this is better is that then your app won't need that much refactoring if you decide somewhere down the road that you want to use something else instead of Handlebars(i.e. Spacebars, the real name of meteors adaption) like jade for meteor.
This is really a comment to the accepted answer. Looking forward to one day hit 50 rep.

Resources