Iron Router works with Meteor 3!

Hi,
we managed to get Iron Router working with Meteor 3.
Beside updating all the package reference to the lastest version, 2 items needed change :

7 Likes

Great effort! I had also been working on updating iron:router, but you’ve beaten me to it.

I have a suggestion, perhaps you might find it a hassle, but it would be helpful if you could recreate your GitHub repositories as forks of the original iron:router packages. That way it would be possible to see the exact diffs from the original packages.

3 Likes

Thanks. Yes I will look into doing it form a fork, I only learned yesterday that this is the preferred way. I will inform you when the forks are available.

1 Like

Hi
I have created 5 pull requests from these forks
[GitHub - polygonwood/iron-router: A client and server side router designed specifically for Meteor.]
[GitHub - polygonwood/iron-layout: Dynamic layout with support for rendering dynamic templates into regions.]
[GitHub - polygonwood/iron-dynamic-template: Dynamic templates and data contexts.]
[GitHub - polygonwood/iron-middleware-stack: Client and server middleware support inspired by Connect.]
[GitHub - polygonwood/iron-controller: Controller class for dynamic layouts.]
with the changes that were needed to make it work with Meteor 3.0.2 (that’s what I have put now in minimal version)
Probably this is not ‘complete’, e.g. I remove a test referring to Fiber in the Middleware stack, this is now perhaps broken, someone with deeper knowledge will have to look into this.
I have an application that uses most of Iron Router functions, both client and server routes. Client routes with multiple controllers and subscription management. So far I don’t see any issues with it in running in 3.0 environment (I’m not half way my refactoring but all pages and forms are alive).
How can I stay informed on what will happen with this ?
regards
Ronny from Polygonwood

1 Like

I reviewed your code and it’s very close to what I implemented in my fork. One change of yours I can’t get my head around:

let go = Meteor.promisify(function (stack, self, done) {
    stack.dispatch(url, self, done);
    console.log('RouteController.prototype.dispatch');
  }, self, true);
  go(stack, self, done);

Meteor.promisify() turns a callback into a function that returns a promise (an async function), however with the change you have made I would expect you to also have needed to do the following:

  1. Use go(stack, self, done).then() to ensure the promise is fulfilled OR
  2. Have the await keyword before go(stack, self, done), which would also require RouteController.prototype.dispatch to be a assigned to an async anonymous function

Is my understanding correct or is there something I have overlooked?

Hi
In normal situation you’re fully right. But the Iron Router code in it’s original version just fires off the dispatch call without any follow up on possible return value (the comment sais ‘it runs in it’s own fiber so we can’t do anything with return value’). We could write out some console logging based on the outcome of the call, but as long as the package doesn’t deal with the result of this call, it’s basically not needed (if you are not interested to wait for or event for the result of an async call you can indeed just let it ‘go’. I have no understanding of the internals of Iron Router, I just gave it a try to get it ‘fixed’ to avoid a heavy effort (now) on getting my application running in 3.0. Maybe over time I will still re-factor to alternative solutions if Iron Router remains unmaintained, but for now it seems to work as before.

Amazing work :clap:

Just added it to the list, sorry for the delay!

2 Likes

Hi, Im new to this, so maybe a silly question - how do I get this updated package? I have a large, old project with Iron router (a lot of both server routes and client routes) and would love to migrate to Meteor 3.x, but could not because of that. But I am not sure how do I get this working?

Magnus

installing the packages from these forks should get it working again

https://github.com/polygonwood/iron-router

https://github.com/iron-meteor/iron-dynamic-template

https://github.com/iron-meteor/iron-middleware-stack

https://github.com/polygonwood/iron-controller

(if you never have used local packages, see Meteor documentation.)

regards
Ronny

1 Like

Thanks, but when Im installing the first one, it fails on a version conflict (iron router requires blaze 2.x.x but Meteor 3.2 has a newer version).
I do not get that as Meteor 3.x does not use Blaze 2.x, so I have can I fix it?

Magnuss

There is no specific dependency on a version of blaze ? There are only api.use(‘blaze’) references in these modifications. Now I notice that I renamed the packages to a local name, could that be a reason ? I provided these only versions to allow construction of a pull request (which I did - but nobody converted that in a real version or iron router so far ?). The community things are not all familiar to me - I’m only trying to help where possible to fix some issues that hampered my conversion to 3.0 …
Ronny

Well, whenever I try to add the package, it fails because the use command relies on a specific version of Blaze (2.x):

While selecting package versions:
error: Conflict: Constraint blaze@2.
Constraints on package “blaze”:

  • blaze@3.0.0-rc300.2 ← launch-scre

  • blaze@3.0.0 ← blaze-html-template

  • blaze@2.0.0 ← iron-dynamic-template-devel 1.0.12

When checking the package.js, there does not seem to any reference to Blaze but instead:

Package.onUse(function (api) {
api.versionsFrom(‘3.0.2’);
// meteor dependencies
api.use(‘underscore’);
api.use(‘webapp’, ‘server’);
api.use(‘tracker’, ‘client’);
api.use(‘ui’);
api.use(‘templating’);

Magnuss
What do you mean with ‘adding the package’ ? I mentioned you have to install the packages, meaning adding them to your local packages directory in your application. You do this by cloning the repo’s e.g. under the packages directory
image
image shows how it looks in my packages directory
Ronny

I was reading the documentation and regarding adding the packages, the only mention was to use "meteor add [name]. So I created the folder “Packages”, extracted the cloned git repo there and then ran the command. So the installation by “adding” is not needed?

No, meteor add … will add a package from the normal list of pacakges (hence an older version of iron router e.g.) by adding the package to your private directory, the build process will use local packages first before looking elsewhere
Ronny

EDIT: Seems to be problem with names, as they contain polygonwood instead of iron

But how to deal with the constraints that require newer versions than those provided?

Conflict: Constraint ironcontroller@1.0.12 is not satisfied by ironcontroller 2.0.0.

Also, the dynamic-template included is of a lower version than that which is requested:

Conflict: Constraint irondynamictemplate@2.0.0 is not satisfied by irondynamictemplate 1.0.12.

Magnuss
all the package names and versions have to match of course
in my .meteor/packages file I have reference to polygonwood:router, in my local package polygonwood:router, I have references to the other packages (which I renamed and renumbered in my local environment), polygonwood:router refers to api.use(‘polygonwood:layout@2.0.0’); which is indeed the local package with that name and version, as what’s in the package.js header of layout package :

Package.describe({
  name: 'polygonwood:layout',
  summary: 'Dynamic layouts which enable rendering dynamic templates into regions on a page.',
  version: '2.0.0',

Ronny
ps: the .meteor/packages file reflects what you do with meteor add … commands (in other words, using the commands or editing the file has the same effect)

1 Like

why not release all these packages under a new name on atmosphere?

David
that’s probably an option, but I’d rather see the Iron Router become a community package and managed by more knowledgeable people. I was lucky to fix the few lines of code and configuration that hampered the compatibility with Meteor 3.x but for more fundamental work I lack the detailed knowledge of Blaze.
regards
Ronny

1 Like

Hi polygonwood

I’m new to this, but I’m currently facing an issue with Iron Router controller hooks after upgrading to Meteor 3.x.

Context:

I’ve already forked and updated the following packages:

  • iron-router
  • iron-controller
  • iron-dynamic-template
  • iron-middleware-stack
  • iron-layout

In several controller hooks like waitOn, onBeforeAction, onAfterAction, and onRerun, the legacy Meteor 2.x code often used Meteor.user(). However, with Meteor 3.x, Now I need to use the async version: Meteor.userAsync() — which means using async/await or Promises.

The Issue:

Iron Router doesn’t seem to support Promises or async functions inside these hooks. So calls like await Meteor.userAsync() or .then(...) inside waitOn or onBeforeAction don’t behave correctly or don’t work at all.

Example:

DummyController = RouteController.extend({
  name: 'App.dummy',

  waitOn: function () { // waitOn can't be async that's why here uses promise.then()
    Meteor.userAsync()
      .then((user) => {
        const showDialog = user?.someFlag;
        if (user) {
          // some logic...
        }
      });
  },

  onBeforeAction: async function () {
    const user = await Meteor.userAsync();
    if (user) {
      // some logic...
    }
    this.next();
  },

  onRerun: async function () {
    const user = await Meteor.userAsync();
    if (!user) {
      // some logic...
    } else {
      this.next();
    }
  },

  action: function () {
    this.render('Dummy');
  }
});

Question:

Have you experienced this limitation?
Is there any known workaround for using Meteor.userAsync() (or any async logic) inside Iron Router hooks?

Any guidance would be really appreciated!

Thanks in advance :pray: