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.
Related
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 */
});
});
I'm having an issue triggering method calls while writing feature tests. I'm not actually given an error in the chimp terminal log, but the server.call line is where the failure is highlighted. I believe this might be related to the folder structure of the app (which I've loosely based on Letterpress) or the order in which the call is defined and then triggered. When I move the method call out to my main.js file (in the root folder of the app), it works without a problem.
hooks.js path: /app/tests/cucumber/features/support/hooks.js
(function(){
module.exports = function() {
this.Before(function() {
console.log("server calling");
server.call("fixtures/resetUsers"); //test stops here
});
};
})();
fixtures.js /app/packages/fixtures/fixtures.js
(function(){
'use strict';
Meteor.methods({
"fixtures/resetUsers": function() {
Meteor.users.remove({});
}
});
})();
package.js /app/packages/fixtures/packages.js
Package.describe({
name: 'forum:fixtures',
version: '0.0.1',
summary: '',
debugOnly: true
});
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.use('ecmascript');
api.addFiles('fixtures.js', 'server');
});
Note: I originally didn't have the fixtures folder wrapped in the packages folder (it still didn't work then) but came across this post by #Xolv.io, the developers of Chimp.js who advised to do so.
with the new chimp, you can just use:
server.execute(function() {
// code you put here will run on the server
});
Check this repository for examples:
https://github.com/xolvio/automated-testing-best-practices/
In your sample repo, if you define a meteor method, 'something', you can call as server.call('something').
If you have a standard method definition (not even a meteor method), say something2=function(){}, with xolvio:backdoor, you can server.execute('something2'). ( calling chimp with --ddp switch)
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();
});
}
});
When I start the Meteor server and navigate to my default route, I see the AppLoading template inside MainLayout (as expected), but the main template never loads even after the subscription is loaded.
I've got a really simple routes.js file (below)
autopublish is still turned on.
I seeded the db and can confirm in the browser console that the subscription is there, and there are items in my Services collection.
Probably missing something really simple here.
/*===================
CONFIGURE DEFAULTS
====================*/
Router.configure({
layoutTemplate: 'MainLayout',
loadingTemplate: 'AppLoading',
notFoundTemplate: 'NotFound'
});
/*===================
CONFIGURE ROUTES
====================*/
Router.route('/', { // DEFAULT ROUTE
name: 'main',
template: 'Main',
waitOn: function() {
return Meteor.subscribe('services');
},
data: function() {
return Services.find();
}
});
I'm guessing you do not have a publication? The client is waiting for a "ready" notification from the publication and is not receiving it, hence nothing is loaded. Remove autopublish and start writing publications.
The autopublish package literally just copies the server DB to the client. You can't subscribe to anything if you do not actually have any publications.
Yesterday I updated meteor and my meteorite packages to their latest versions. Today, iron router is not behaving. When I navigate to a parameterized route, the parameter is not loaded. What gives? I have looked at the documentation for iron-router, and it still specifies the same scheme I was using before.
This is the routes file I have created
Router.map(function() {
this.route('home', {
path: '/'
});
this.route('list', {
path: '/:_id',
waitOn: function() {
return Meteor.subscribe('lists')
},
data: function() {
var list = Lists.findOne({
_id: this.params._id
});
Session.set('listId', list._id);
return list;
}
});
});
When I load a page to http://localhost/1234 the path in iron router is correctly set to /1234 but it does not recognize the last bit as a parameter.
I am afraid that what is empty is not your this.params object but rather the list document, at least for the first time the route is being executed. This is caused, of course, by the latency related to fetching server data.
You may be thinking that it shouldn't happen because you have used the waitOn hook. But for this to work you would also need to do two other things:
Router.onBeforeAction('loading');
and define the loading template:
Router.configure({
loadingTemplate: 'someTemplateName'
});
so please update if you haven't done it already.