iron-meteor / iron-router

A client and server side router designed specifically for Meteor.
MIT License
1.98k stars 413 forks source link

Two different routes for isCordova and isClient respectively #1082

Open ghost opened 9 years ago

ghost commented 9 years ago

Hi there,

how can I have a Meteor project with the BrowserApp being different from the SmartphoneApp, meaning I need two completely different routing tables, like so

Router.map(function() {
  if (Meteor.isCordova) {
    this.route('homeCordova', {
      path: '/'
    });
  }

  if (Meteor.isClient) {
    this.route('homeWeb', {
      path: '/'
    });
  }
}

But it seems not to be working correctly so far. Is this planned for the future, to also support projects with Cordova?

tmeasday commented 9 years ago

I can't see why this wouldn't work. What goes wrong?

boustanihani commented 9 years ago

When Meteor.isCordova is true Meteor.isClient will also be true because Cordova is a client environment so your first mapping will always be overridden by the second one, you should use if/else:

Router.map(function() {
    if (Meteor.isCordova) {
        this.route('homeCordova', {
            path: '/'
        });
    } else if (Meteor.isClient) {
        this.route('homeWeb', {
            path: '/'
        });
    }
});

I don't know which iron-router version you are using, but as far as I know the map() function has been deprecated, so try this instead:

Router.route('/', {
    action: function() {
        if (Meteor.isCordova) {
            this.render('homeCordova');
        } else { 
            this.render('homeWeb');
        }
    }
});
ghost commented 9 years ago

Hi there,

in the meantime I switched to two completely different apps, one for Web and one for Smartphones. For now I am gonna keep it this way, but when I have the time will try what you wrote @boustanihani.

As for the router.map(): Thank you, I took that from the Differential Boilerplate, but already thought that the boilerplate itself is not up to date.

I'll report when I tried it out.

ghost commented 9 years ago

Only objection against one app vs two coming into my mind would be that probably the whole js package is distributed to cordova as well as the web client, meaning that the cordova app is also in the browser and vice versa, which results in longer loading times and larger app size and security thoughts. But the deployment is easier then and also the scaling. I have to try this out.

ghost commented 9 years ago

In the end I figured, if you want two different apps - that is for web and smartphone - you probably should have two completely different Meteor apps, since otherwise you have double the size of the app. Also this way you can have different packages for web and android/ios respectively. How it is done: http://stackoverflow.com/questions/13115723/how-can-i-share-mongodb-collections-between-meteor-apps

Wenape commented 9 years ago

@tmeasday Is it possible to define the controller and name conditionally as well?

Router.route('/', {
  name: Meteor.isCordova ? 'SelectionPage' : 'SplashScreen',
  action: function() {
    if (Meteor.isCordova) {
      this.render('SelectionView');
    } else { 
      this.render('SplashScreen');
    }
  },
  controller: Meteor.isCordova ? 'SelectionController' : 'SplashController'
});

This doesn't work for me, I get Error: No route found named "SelectionPage". I'm guessing because the name can't be set this way.

Wenape commented 9 years ago

My bad, this actually works. I forgot to add the 'SelectionPage' route for when not in cordova.