Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iron Router conflict with Angular-UI router

I'm using an Angular-Meteor solution with my web app and I opted to use angular-ui:router over iron-router. I ran into issues when I decided to use Houston Admin which uses iron-router under the hood. Is there a way to restrict iron-router to /admin/* routes?

When I navigate my app normally, I get a message from iron-router in the view saying the route doesn't exist but it does under angular-ui:rouer.

EDIT: Defining the routes within iron router is getting me somewhere but now my angular-ui view is being displayed twice.

//Iron-Router
Router.route('/(.*)', function (){});

//UI-Router
angular.module("test").config(
function($urlRouterProvider, $stateProvider, $locationProvider){

$locationProvider.html5Mode(true);

$stateProvider
  .state('main', {
    url: '/',
    templateUrl: 'client/app/main/views/main.ng.html',
    controller: 'MainCtrl'
  })
  .state('profile',{
    url: '/profile/:user_id',
    templateUrl: 'client/app/main/views/profile.ng.html',
    controller: 'ProfileCtrl',
    resolve: {
      currentUser: function($meteor){
        return $meteor.requireUser();
      }
    }
  });

$urlRouterProvider.otherwise("/");

});

EDIT2: When the page refreshes it doesn't double display the view. That happens after I change route via ui-router. I'm thinking I might need to give iron router something to display like an empty tag.

SOLUTION: See my answer below, for a coded example check out the github here https://github.com/cleor41/router-example.

like image 480
CleoR Avatar asked Jun 24 '15 19:06

CleoR


3 Answers

EDIT: IF anyone wants to see an example, check out the link here https://github.com/cleor41/router-example

Instead of trying to sidestep iron router I had to use it, at least for the initial page load. My initial index.html changed from this.

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <base href="/">
  <title>test</title>
</head>

<body>
  <navbar></navbar>
  <div ui-view></div>
</body>

to this

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <base href="/">
  <title>test</title>
</head>

<body>
</body>

And I created a template that encapsulated the body.

<template name="default">
  <navbar></navbar>
  <div ui-view></div>
</template>

Last but not least I had to change my iron route to this.

Router.route('/(.*)', function(){
  this.render('default');
});

This works since iron router will only render a template once and then the ui router kicks in. My views don't display twice, I can use Houston Admin and the two routers play nice.

NOTE: It should be noted that if you want to use Houston Admin alongside ui router, the ui router will need to catch all of the admin/* routes and then event.preventDefault() inside of $stateChangeStart. This way "urlRouterProvider.otherwise("/")" doesn't mess with the address bar when you're on the Meteor side of things.

like image 102
CleoR Avatar answered Nov 08 '22 03:11

CleoR


If there are routes you want to be handled in one router but not the other (doesn't matter which one), you should add that route to both routes to handle, but in one of them don't do anything when it is handled.

You have to do this so that the default behaviour of that route won't happen (usually a redirect to somewhere).

If this answer doesn't help, please copy/paste your routes here so I can better look at what's happening.

like image 4
Urigo Avatar answered Nov 08 '22 03:11

Urigo


Acutally. You don't need to define template name="index" /template. You just need to define Router.route('/', function(){

}); (At the top level of route.ng.js)

No need to render anything inside Router.route, and also, the index.html should be as it was. And define correspondent state in ui-router: .state('admin1',{ url: '/admin' }) .state('admin2',{ url: '/admin/*path' });

And then everything will just work fine. This is how I did it.

like image 1
youclavier Avatar answered Nov 08 '22 01:11

youclavier