I'm doing a tutorial from https://thinkster.io/tutorials/mean-stack called flapper news. I have completed the tutorial and the system work fine. But, I was thinking doing an inline template in a single file is not a good practice specially if you're doing a big project. So I tried to separate those templates into files(.html). Unfortunately the html file cannot be displayed in the ui-view. There was no error in the console nor the server. I tried to change my index.ejs file in the view folder into the public folder and rename it to index.html. Still not working.
Here is my index.html:
<html>
<head>
<title>Flapper News</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="/javascripts/angularapp.js"></script>
<style>
.glyphicon-thumbs-up {
cursor: pointer
}
</style>
</head>
<body ng-app="flapperNews">
<nav class="navbar navbar-default pull-right" ng-controller="NavCtrl">
<ul class="nav navbar-nav">
<li ng-show="isLoggedIn()"><a>{{ currentUser() }}</a></li>
<li ng-show="isLoggedIn()">Log Out</li>
<li ng-hide="isLoggedIn()">Log In</li>
<li ng-hide="isLoggedIn()">Register</li>
</ul>
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
Here is one of the html file in the same public folder(home.html):
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy: '-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span> {{post.upvotes}}
<span ng-show="post.author"> posted by <a>{{post.author}}</a> |
</span>
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()" ng-show="isLoggedIn()" style="margin-top:30px;">
<div ng-hide="isLoggedIn()">
<h3>You need to Log In or Register before you can add a post.</h3>
</div>
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Title" ng-model="title"></input>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Link" ng-model="link"></input>
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
public/javascripts/angularApp.js:
var app = angular.module('flapperNews', ['ui.router']);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: 'MainCtrl',
resolve: {
postPromise: [
'posts',
function(posts) {
return posts.getAll();
}
]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl',
resolve: {
post: [
'$stateParams',
'posts',
function($stateParams, posts) {
return posts.get($stateParams.id);
}
]
}
})
.state('login', {
url: '/login',
templateUrl: '/login.html',
controller: 'AuthCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
})
.state('register', {
url: '/register',
templateUrl: '/register.html',
controller: 'AuthCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
});
$urlRouterProvider.otherwise('/');
}
]);
fyi, the ".state('home', { url:" was ".state('home', { url: '/home'" but it show an error so I change it to "url: '/'" and the error was gone. But still the ui-view cannot display the templates.
This is the output:
enter image description here
Anyone has any idea on how to solve this? Does bower has anything to do with this?
You don't need the script tag once you have the template on the separate file. Remove it and it should works. You can just use the path of the file for the templateURL then
Sometimes you will something like this just like you have,
<script type="text/ng-template" id="template.html">
... some template stuff
</script>
That script tag was actually for having the template on the same file as the main template file, and you can use templateUrl with the value of the id attribute just like usual. It will treat the body of the script tag as a file of template.html since the value of the id is template.html
Related
I need help with routing in AngularJS. I am new and don't understend why it doesn't work.
I have a small application with to pages.
my app.js:
var app = angular.module("suggestionBox", ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'views/home.html'
})
.when('/suggestion/:id', {
controller: 'SuggestionController',
templateUrl: 'views/suggestion.html'
})
.otherwise({
redirectTo: '/'
});
});
my view:
<form ng-submit="addSuggestion()" style="margin-top: 50px">
<h3> Submit Your Suggestion </h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Great ideas here" ng-model="data.title">
</div>
<button type="submit" class="btn btn-primary">Suggest</button>
</form>
<div class="posts-wraper">
<div class="suggestion" ng-repeat="post in posts | orderBy: '-upvotes'">
<h3>{{ post.title }}</h3>
<div>
<p>
<span class="glyphicon glyphicon-plus-sign" ng-click="upVote(post)"></span> Upvotes: {{post.upvotes}}
</p>
<a class="comment" href="#/suggestion/{{$index}}">Comments</a>
</div>
</div>
</div>
main page:
<!DOCTYPE html>
<html>
<head>
<title>Suggestion Box</title>
<script type="text/javascript" src="js/vendor/angular.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet">
<script src="https://code.angularjs.org/1.2.28/angular-route.min.js"></script>
</head>
<body ng-app="suggestionBox">
<div class="col-md-2"></div>
<div class="col-md-8">
<div ng-view></div>
</div>
<div class="col-md-2"></div>
<!-- Modules -->
<script type="text/javascript" src="js/app.js"></script>
<!-- Controllers -->
<script type="text/javascript" src="js/controllers/HomeController.js"></script>
<script type="text/javascript" src="js/controllers/SuggestionController.js"></script>
<!-- Services -->
<script src="js/services/suggestions.js"></script>
</body>
</html>
And when I'm on home page and want to go to /suggestion/:id I click reference and nothing happen. But I have the following url: "http:// localhost:8080/#!/#suggestion%2F0" and stay at the home page. If I type url by hand like this: "http:// localhost:8080/#!/suggestion/0" all is well and I go to suggestion page. Then I press back:
Back
and it works! I am on home page, but url is: "http:// localhost:8080/#!/#%2F"
I don't know why! Please help me with it.
How about something like that check the Plunker if code snippet doesn't make any sense also pay attention to markup changes in the index, home and suggestion.html in plunker. You can edit the plunker and see the URL changes by launching the plunker preview in separate window.
app.js
var app = angular.module("SuggestionBox", ['ngRoute']);
app.config(["$routeProvider", "$locationProvider", function($routeProvider, $locationProvider){
$locationProvider.hashPrefix(''); // magic line
$routeProvider
.when('/',{
controller: "HomeController",
templateUrl: "views/home.html"
})
.when('/suggestion/:id',{
controller: "SuggestionController",
templateUrl: "views/suggestion.html"
})
.otherwise({
redirectTo: '/'
});
}]);
I am making a simple Angular application that has an index.html which loads other HTML pages as views based on which navbar item selected; however, the routing is not working as expected. The main.html view is loaded fine, but none of the other views are loaded, and the URL is not what I expect.
The URL that shows up in the browser after an item is selected is localhost:8081/#!/#pageName. I do not know where the '!' is coming from, and there should not be a hash before the pageName. The URL that I am expecting is localhost:8081/#/pageName
app.js:
'use strict';
var app = angular.module('videoGamesApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/rankedLists', {
templateUrl: 'views/rankedLists.html',
controller: 'RankedListsCtrl'
})
.when('/addGame', {
templateUrl: 'views/addGame.html',
controller: 'AddGameCtrl'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('MainCtrl', function($scope) {
$scope.message = 'THIS IS THE MAIN PAGE';
});
app.controller('RankedListsCtrl', function($scope) {
$scope.message = 'THIS IS THE RANKED LISTS PAGE';
});
app.controller('AddGameCtrl', function($scope) {
$scope.message = 'THIS IS THE ADD GAME PAGE';
});
app.controller('ContactCtrl', function($scope) {
$scope.message = 'THIS IS THE CONTACT PAGE';
});
index.html:
<!doctype html>
<html ng-app="videoGamesApp">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.css">
</head>
<body ng-controller="MainCtrl">
<header>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">GAMING </a>
</div>
<ul class="nav navbar-nav">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-trophy"></i> Ranked Lists</li>
<li><i class="fa fa-gamepad"></i> Add a Game</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="sr ch-term">
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</nav>
</header>
<div id="main">
<div ng-view=""></div>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
Why are the other views not loading? Where is the exclamation point coming from in the URL? Why is there a hash before the pageName (I expect one hash, not two).
Why are the other views not loading?
The reason why your views are not loaded is because you hit the route. You use 1.6 angular and expect the behaviour from 1.5. There has been a change in location hash-prefix:
Due to aa077e8, the default hash-prefix used for $location hash-bang
URLs has changed from the empty string ('') to the bang ('!'). If your
application does not use HTML5 mode or is being run on browsers that
do not support HTML5 mode, and you have not specified your own
hash-prefix then client side URLs will now contain a ! prefix. For
example, rather than mydomain.com/#/a/b/c the URL will become
mydomain.com/#!/a/b/c.
If you actually want to have no hash-prefix, then you can restore the
previous behavior by adding a configuration block to you application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix(''); }]); Source
What to do?
1. Set HTML5mode true
$locationProvider.html5Mode(true);
and in html set base in html header:
<base href="/">
Lastly change <a ng-href="#pagename"> to
<a ng-href="pagename">
2. Go back to old behaviour from 1.5 - set hash prefix manually
This will make your app work as you expect in your question.
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
Why is there a hash before the pageName?
The way you link is treated as a hashtag anchor tag. Which will scroll down to the current div with the given id. If you fix your problem with one of the above reasons this will be fixed aswell.
I am trying to migrate my Angular routing from routeProvider to stateProvider with below code, I don't see states content when click on navbar, any idea what's wrong?
app.js
angular.module('sampleApp', ['ui.router', 'MainCtrl', 'NerdCtrl', 'NerdService'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'MainController'
})
.state('nerd', {
url: '/nerd',
templateUrl: 'views/nerd.html',
controller: 'NerdController'
});
});
main.html
<body ng-app="sampleApp" ng-controller="NerdController">
<div class="container-fluid">
<!-- HEADER -->
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" ui-href="home">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li><a ui-sref="nerd">Nerds</a></li>
</ul>
</nav>
<!-- ANGULAR DYNAMIC CONTENT -->
<div ng-view></div>
</div>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-ui-router/release/angular-ui-router.min.js"></script>
<!-- ANGULAR CUSTOM -->
<script src="js/controllers/MainCtrl.js"></script>
<script src="js/controllers/NerdCtrl.js"></script>
<script src="js/services/NerdService.js"></script>
<script src="js/appRoutes.js"></script>
<script src="js/app.js"></script>
</body>
Use ui-view instead of ng-view, in that element ui-router will put template based on $location changes.
<div ui-view></div>
Remove ng-controller from body. Using, ui-router, It handles injecting the right controller for the right templates that you have defined in your $stateProvider.
Like Pankaj has pointed out, change ng-view to ui-view.
Change ui-href="home" to ui-sref="home"
I have solution for this question. some time ago i was doing the same:
in app.js:
var app=angular.module('ppl_App',['ui.router','oc.lazyLoad','ngStorage','ngFileUpload'])
Provide UI-Routing content ( In app.js ):
angular.module('ppl_App').config(function($stateProvider,$urlRouterProvider){
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('root',{
views: {
'#':{
templateUrl:'index.html'
},
'header#':{
templateUrl: 'app/views/common/header.html'
},
'content_left#':{
templateUrl: 'app/views/common/content-left.html'
},
'content_right#':{
templateUrl: 'app/views/common/contentright.html'
},
'footer#':{
templateUrl: 'app/views/common/footer.html'
}
}
})
.state('root.login',{
url:'/login',
views:{
'contentRight#root':{
templateUrl:'app/views/login.html',
controller:'loginCtrl'
},
},
})
.state('root.register',{
url:'/register',
views:{
'contentRight#root':{
templateUrl:'app/views/register.html',
controller:'registerCtrl'
},
},
})
});
See the view name in the snapshot ( In red color shape) :
Now you can use these views in your html page. ( I have used in index.html )
<body ng-app="ppl_App">
<div class="navbar navbar-inverse navbar-fixed-top" ui-view="navigation">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
<a class="brand" href="">PPL</a>
<div class="pro_info pull-right">
<div class="pro_icn"><img src="app/assests/images/pic_small.png"></div>
<div class="pro_txt">Me<b class="caret"></b></div>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li><a tabindex="-1" href="#">My Profile</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="header header_fixed" ui-view="header">
<!-- //header goes here -->
</div>
<div class="container">
<div class="content_rgt" ui-view="content_right">
<!-- //right content goes here -->
</div>
<div class="content_lft" ui-view="content_left">
<!-- //left content goes here -->
</div>
</div>
<div class="clear"></div>
</div>
<div class="footr" ui-view="footer">
<!-- //footer goes here -->
</div>
<script type="text/javascript" src="app/app.js"></script>
</body>
See how to use in html in snapshot ( In red color box ):
You can redirect on this particular views using ui-sref, like this:
<div class="addtnal_acnt">
<a ui-sref="root.register">Create My Account Now !</a>
</div>
<div class="addtnal_acnt">
<br>
<a ui-sref="root.login"> Loging Again !</a>
</div>
You can redirect from controller code ( .js file ) using $state.go() :
$state.go('root.login');
or
$state.go('root.register');
I'm new to AngularJS and I'm trying to make a slider work that I copied from an example online.
At the moment, I have the slider coming up on the page I want it to (gallery.html) and the automatic picture change works, but, when I try to press the next/previous button, it just takes me to a random page with nothing on it.
I think the problem is with my hrefs on the arrows but I honestly don't know where to go from here. Also, is my slider directive in the right place (at the top of gallery.html) ?
File structure:
Photography
- bower_components
- css
----- stylemain.css
- img
----- phones
---------- ...a bunch of png files...
- js
----- app.js
----- controller.js
- partials
----- gallery.html
- phones
----- ...a bunch of json files...
- index.html
This is my index.html:
<!DOCTYPE html>
<html lang="en" ng-app="mainApp">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<!--<link rel="stylesheet" href="css/app.css">-->
<link rel="stylesheet" href="css/stylemain.css">
<!-- JS & ANGULAR FILES -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-touch.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.10.3/TweenMax.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-touch.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<script src="js/app.js"></script>
<script src="js/controller.js"></script>
<!--<script src="js/directives.js"></script>-->
</head>
<body>
<div class="template-header">
<div class="template-container">
<div class="template-logo">
<h1><a href="#/">title</h1>
</div>
<div class="template-nav">
<ul>
<li>Home</li>
<li>Gallery</li>
<li>Music</li>
<li>Other-work</li>
</ul>
</div>
</div>
</div>
<!-- BODY CONTENT -->
<div class="dynamic-body" ng-view></div>
</body>
This is my app.js:
'use strict';
/* App Module */
var mainApp = angular.module('mainApp', [
'ngRoute',
'galleryControllers'
]);
mainApp.config(['$routeProvider',
function($routeProvider){
$routeProvider
.when('/', {
templateUrl:'partials/main.html',
})
.when('/gallery', {
templateUrl:'partials/gallery.html',
controller: 'mainImageCtrl',
})
.when('/:phoneId', {
templateUrl: 'partials/gallery-image.html',
controller: 'singleImageCtrl'
})
.when('/music', {
templateUrl: 'partials/music.html',
controller: 'singleImageCtrl'
})
.when('/other-work', {
templateUrl: 'partials/other-work.html',
controller: 'singleImageCtrl'
});
}
]);
This is my controller.js:
'use strict';
/* Controllers */
var galleryControllers = angular.module('galleryControllers', [
'ngAnimate'
]);
galleryControllers.controller('mainImageCtrl',['$scope', '$http',
function($scope, $http){
$http.get('phones/phones.json').success(function(data){
$scope.images = data;
});
}]);
galleryControllers.directive('slider', function($timeout) {
return {
restrict: 'AE',
replace: true,
scope: {
images: '='
},
link: function(scope, elem, attrs) {
scope.currentIndex=0;
scope.next=function(){
scope.currentIndex<scope.images.length-1?scope.currentIndex++:scope.currentIndex=0;
};
scope.prev=function(){
scope.currentIndex>0?scope.currentIndex--:scope.currentIndex=scope.images.length-1;
};
scope.$watch('currentIndex',function(){
scope.images.forEach(function(image){
image.visible=false;
});
scope.images[scope.currentIndex].visible=true;
});
/* Start: For Automatic slideshow*/
var timer;
var sliderFunc=function(){
timer=$timeout(function(){
scope.next();
timer=$timeout(sliderFunc,2000);
},2000);
};
sliderFunc();
scope.$on('$destroy',function(){
$timeout.cancel(timer);
});
/* End : For Automatic slideshow*/
}
};
});
// galleryControllers.controller('singleImageCtrl',['$routeParams','$scope',
// function($scope, $routeParams){
// $scope.phoneId = $routeParams.phoneId;
// }]);
This is my gallery.html:
<slider images="images"/>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<!--Sidebar content-->
Search: <input ng-model="query"/>
Sort by:
<select ng-model="orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
</div>
<!--Body content-->
<!-- <ul class="phones">
<li ng-repeat="phone in phoneImages | filter:query | orderBy:orderProp" class="thumbnail">
<img ng-src="{{phone.imageUrl}}">
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul> -->
<div class="slider">
<div class="slide" ng-repeat="image in images" ng-show="image.visible">
<img ng-src="{{image.imageUrl}}" />
</div>
<div class="arrows">
<a href="#" ng-click="prev()">
<img src="img/left-arrow.png" />
</a>
<a href="#" ng-click="next()">
<img src="img/right-arrow.png" />
</a>
</div>
</div>
</div>
</div>
phones.json is just a json file with fields on different phones etc.
Thanks in advance, all help is much appreciated!!!!
test with https://github.com/angular-ui/ui-router
and every time you try to call a route used =
<a ui-sref="root">link</a>
appModule.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/signin');
$stateProvider
.state("root", {
url: "/signin",
templateUrl: "views/signin.html",
controller: 'AuthController'
})
with ui-sref="root" already know to what route to go.
I trying to use ui.routing but using stateProvider I get error : Could not resolve 'newUser' from state 'login'.
Here is my config:
index.html
<html lang="en" ng-app="mainApp">
<section id="mainBody">
<div class="continer">
<div>
<a ui-sref="main">Header</a>
<a ui-sref="login">Login</a>
<a ui-sref="list2">List2</a>
</div>
<div class="row" ui-view></div>
<div>Footer</div>
</div>
</section>
</html>
index.js
var mainApp = angular.module('mainApp', [, 'ui.router', 'ui.bootstrap']);
mainApp.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('login', {
url: 'login',
templateUrl: '../../pages/login.html'
});
}]);
login.html
<!DOCTYPE html>
<html lang="en" ng-app="loginApp">
<body>
<section id="form">
<!--form-->
<div class="container login-user">
<div class="row">
<a type="button" class="btn btn-loginUser btn-default col-xs-12 col-sm-2" ui-sref="existingUser">Existing user</a>
<a type="button" class="btn btn-loginUser btn-default col-xs-12 col-sm-2" ui-sref="newUser">New user</a>
</div>
<div class="row" ui-view="userInfo">
</div>
</div>
</section>
</body>
</html>
login.js
var loginApp = angular.module('loginApp', ['ui.router', 'ngSanitize', 'ui.bootstrap']);
loginApp.config(['stateProvider', function (stateProvider) {
$stateProvider
.state('existingUser', {
views: {
"userInfo": {
url: 'existinguser',
templateUrl: '../../pages/loginForms/existingUserForm.html',
controller: 'existingUserCtrlr'
}
}
})
.state('newUser', {
views: {
"userInfo": {
url: 'newUser',
templateUrl: '../../pages/loginForms/newUserForm.html',
controller: 'newUserCtrlr'
}
}
});
}]);
Maybe someone can tell me what I missed?
loginApp and mainApp are two different modules. You cant go to newUser from login because login is defined on mainApp. While other two routes are defined on loginApp. Define all routes on same module.