Angular ui-router doesn't work - javascript

I'm new to Angular, i've been trying to use ui-router in this project, but ui-view doesn't show anything, did i miss something?.
I'm trying to build a mean app, the folder structure is the following:
The app folder is where the angular app is located.
<!DOCTYPE html>
<html lang="en" ng-app="TimeWaste">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
</head>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="">
<input type="text" ng-model="login.email">
<input type="password" ng-model="login.password">
<button>Login</button>
<a ui-sref="signUp">Create an account</a>
</div>
</div>
</nav>
<body>
<div ui-view></div>
</body>
<script src="node_modules/angular/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script src="app/app.js"></script>
<script src="app/signup/signup-controller.js"></script>
</html>
this is the app.js
(function()
{
angular.module('TimeWaste',['ui.router'])
.config(function($stateProvider)
{
$stateProvider
.state('signup',{
url:"/signup",
templateUrl: "app/signup/signup.html",
controller:"SignupController"
})
})
}());
the signup.html view
<div class="row">
<div class="col-sm-6">
<div class="row">
<strong>Email Address:</strong>
<input type="text" ng-model="newUser.email" class="form-control">
</div>
<div class="row">
<strong>Password:</strong>
<input type="password" ng-model="newUser.password" class="form-control">
</div>
<button ng-click="createUser()">Submit</button>
</div>
</div>
and the signup controller
(function()
{
angular.module('TimeWaste')
.controller('SignupController', ['$scope','$state',function($scope,$state){
}]);
}());

It may typo and path missing !!
in html used <a ui-sref="signUp">Create an account</a> but in $stateProvider used signup so need to change signUp to signup.
and I assume your app.js is in app directory because you use
<script src="app/app.js"></script> in home page.
if right then your template path need to change templateUrl: "signup/signup.html",
However you can configure ui.route to be case insensitive.
like:
.config(function($stateProvider,$urlMatcherFactoryProvider,)
{
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$stateProvider
.state('signup',{
url:"/signup",
templateUrl: "signup/signup.html",
controller:"SignupController"
})
})

Related

AngularJS: Browse page content not being displayed in Homepage

I'm a newbie to Angular and working on a project but I'm having an issue with displaying info in two different pages.
I have a browse page that displays profiles
I also have a homepage where I want to display the contents of the browse page plus other miscellaneous information.
To do that I created a component(browsePage)
Then I added the component to the home.view.html
<browse-page></browse-page>
but the profiles don't show up.
In my browse page the profiles do show up.
My code:
app.config.js
$routeProvider
.when('/home', {
RouteData: {
bodyStyle: {
//'background': 'url(../images/bg-7.jpg)repeat'
'background-color': 'white'
}
},
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'vm'
})
.when('/browse', {
RouteData: {
bodyStyle: {
//'background': 'url(../images/bg-10.jpg)repeat'
'background-color': 'white'
}
},
controller: 'BrowseController',
templateUrl: 'browse/browse.view.html',
controllerAs: 'vm'
})
home.controller.js
angular.module("mango").controller("HomeController", HomeController);
function HomeController() {
}
angular.module('mango').controller('ExampleController', ['$cookies', function($cookies) {
}]);
home.view.html
This is the home page<br>
Miscellaneous info goes here
<browse-page></browse-page>
Miscellaneous info goes here<br>
end of home page
browse.component.js
console.log("In browse.component.js");
angular.module("mango").component("browsePage",{
templateUrl:"browse/browse.view.html",
controller:BrowseController
});
browse.controller.js
angular.module("mango").controller("BrowseController", BrowseController);
BrowseController.$inject = ["$rootScope","$location","AuthenticationService","$http"];
function BrowseController($rootScope, $location, AuthenticationService, $http){
var vm = this;
$http.get('browse_profiles.json').success(function(data){
vm.data = data;
console.log("data==>");
console.log(data);
});
}
browse.view.html
<br><br>
<!-- Page Content -->
<div class="container">
<!-- Jumbotron Header -->
<header class="jumbotron hero-spacer" >
<form ng-submit="submit()" ng-controller="ExampleController">
Enter text and hit enter:
<input type="text" ng-model="text" name="text" />
<input type="submit" id="submit" value="Submit" />
</form>
</header>
<hr>
<!-- Page Features -->
<div class="row text-center">
<img id="mySpinner" src="/images/loader.gif" ng-show="loading" />
{{alpine}}
<div class="col-md-3 col-sm-6 hero-feature" ng-repeat="profile in vm.data">
<div class="thumbnail">
<img src="{{profile.thumbnail}}" alt="">
<div class="caption">
<div class="username-status">
<span class="username pull-left"><a ng-href="#/profile/{{profile.username}}">{{profile.username}}</a></span>
<p ng-class-odd="'circle odd'" ng-class-even="'circle even'"></p>
</div>
</div>
</div>
</div>
</div>
<!-- /.row -->
<hr>
<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12">
<p>Copyright © Your Website 2014</p>
</div>
</div>
</footer>
</div>
End of browse view.
<br><br>
index.html
<!doctype html>
<html lang="en" ng-app="mango">
<head>
<meta charset="utf-8">
<title>Mango</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="app.config.js"></script>
<script src="login/route-data.js"></script>
<script src="navigation_menu/navigation_menu.config.js"></script>
<script src="browse/browse.controller.js"></script>
<script src="browse/browse.component.js"></script>
<script src="home/home.controller.js"></script>
<script src="profile/profile.controller.js"></script>
<script src="settings/settings.controller.js"></script>
<script src="login/login.controller.js"></script>
<script src="login/app-services/authentication.service.js"></script>
<script src="login/app-services/flash.service.js"></script>
<script src="login/app-services/user.service.local-storage.js"></script>
</head>
<body ng-style="RouteData.get('bodyStyle')" ng-cloak>
<navigationmenu ng-if="location.path() !== '/login'"></navigationmenu>
<ng-view autoscroll></ng-view>
</body>
</html>
I'm not getting any errors in the console.You can ignore the GET error.
What do I need to do to fix my problem?
I'm starting to think th
Thanks in advanced.
I think in your component, you haven't specified controllerAs, when you goto /browse, your browseView.html is getting the controller instance as vm, but when browseView.html is loaded through component,it is not getting the controller instance, as it is not getting instantiated like it is done, in routeProvider.
Try doing,
angular.module("mango").component("browsePage",{
templateUrl:"browse/browse.view.html",
controller:BrowseController,
controllerAs: 'vm'
});
Hope, this solves the issue.

Error using ui-router: "$injector:modulerr"

I am following AngularJS Tutorial: Learn to Build Modern Web Apps with Angular and Rails by Thinkster and faced one problem.
After making an inline template I have a blank page and an error $injector:modulerr with following details:
Failed to instantiate module flapperNews due to:
Error: [$injector:modulerr] http://errors.angularjs.org/1.2.19/$injector/modulerr?p0=...)
at Error (native)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:6:450
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:34:97
at Array.forEach (native)
at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:7:280)
at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:33:207)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:33:284
at Array.forEach (native)
at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:7:280)
at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:33:207
Here is my code.
Module:
# app.js
var app = angular.module('flapperNews', ['ui-router']);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
View:
# index.html
<!DOCTYPE html>
<html>
<head>
<title>Thinkster's AngularJS Tutorial</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="app.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<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}} upvotes
<span style="font-size: 20px; margin-left: 10px;">
<a ng-href="post.link" ng-show='post.link'>{{post.title}}</a>
<span ng-hide="{{post.link}}">{{post.title}}</span>
</span>
</div>
<form ng-submit="addPost()" style="margin-top: 30px">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" placeholder="Title" class="form-control" ng-model="title">
</div>
<div class="form-group">
<input type="text" placeholder="Link" class="form-control" ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
Module name is 'ui.router' not 'ui-router'.
Simply change this line to:
var app = angular.module('flapperNews', ['ui.router']);
Your app.js requires the ui-router library but the library was loaded after the app. You should correct the loading order of your script files:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="app.js"></script>
The module name required for your app is ui.router not ui-router.

$routeProvider not working properly in AngularJS (crashing the website)

I was following some random YT tutorial on using Angular's $routeProvider and the result - contrary to the video - is not working for me. Instead, what I get is crashed website and this error logged in Chrome's console: Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.8/$injector/modulerr?p0=site&p1=Error%3A%20…ogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.4.8%2Fangular.min.js%3A41%3A249) By following the trail, I found that there's something wrong with `$routeProvider', but beats me if I know what. Here's my code:
var site = angular.module('site', []).
config(function($routeProvider){
$routeProvider.
when('/home', {template:'/pages/home.html'}).
when('/', {template:'/pages/home.html'}).
when('/in-play', {template:'/pages/in-play.html'}).
when('/popular', {template:'/pages/popular.html'}).
otherwise({redirectTo:'/home', tempalte:'/pages/home.html'});
});
function MainCtrl($scope, $location) {
$scope.setRoute = function(route) {
$location.path(route);
};
};
And here are all the HTMLs (I'm working with ng-include also):
<!DOCTYPE html>
<html ng-app="site">
<head>
<link rel="stylesheet" href="css/style.css">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="scripts/app.js"></script>
<title>Pre-Demo</title>
</head>
<body ng-controller="mainStaysCtrl">
<header class="header" ng-include="'pages/header.html'"></header>
<nav class="nav" ng-include="'pages/nav.html'"></nav>
<div class="main">
<div class="left-col">
<div class="quick links" ng-include="'pages/quick_links.html'"> </div>
<div class="quick-inplay links" ng-include="'pages/quick_inplay_links.html'"></div>
<div class="winner links" ng-include="'pages/winner_links.html'"></div>
</div>
<div class="center-col" ng-controller="mainCtrl">
<div class="wraper" ng-view ng-controller="jsonCtrl"></div>
</div>
<div class="right-col">
<div class="expert-mixer" ng-include="'pages/mixer.html'"></div>
<div ng-include="'pages/twitter.html'"></div>
</div>
</div>
</body>
</html>
//included page that has the call for $routeProvider
<div class="events">
<div class="bullet">
<div class="bullet-padding">
<div ng-click="setRoute('in-play')" class="bullet-link">In-Play Links</div>
</div>
</div>
</div>
Could someone please tell me what's wrong?
EDIT
After Antiga's answer I got it to load the page. Everything besides the content that is to be loaded with ng-view and for which $routeProvider was set up in the first place. Here's the updated code:
var site = angular.module('site', ['ngRoute']).
config(function($routeProvider){
$routeProvider.
when('/home', {templateUrl:'/pages/home.html'}).
when('/', {templateUrl:'/pages/home.html'}).
when('/in-play', {templateUrl:'/pages/in-play.html'}).
when('/popular', {templateUrl:'/pages/popular.html'}).
otherwise({redirectTo:'/home', tempalteUrl:'/pages/home.html'});
});
site.controller('mainStaysCtrl', function($scope) {
$scope.setRoute = function(route) {
$location.path(route);
};
});
and HTML
<body ng-controller="mainStaysCtrl">
<header class="header" ng-include="'pages/header.html'"></header>
<nav class="nav" ng-include="'pages/nav.html'"></nav>
<div class="main">
<div class="left-col">
<div class="quick links" ng-include="'pages/quick_links.html'"></div>
<div class="quick-inplay links" ng-include="'pages/quick_inplay_links.html'"></div>
<div class="winner links" ng-include="'pages/winner_links.html'"></div>
</div>
<div class="center-col">
<div class="wraper" ng-view ></div>
</div>
<div class="right-col">
<div class="expert-mixer" ng-include="'pages/mixer.html'"></div>
<div ng-include="'pages/twitter.html'"></div>
</div>
</div>
You are not including the routing module.
Read up on this here so that you actually understand it first: https://docs.angularjs.org/api/ngRoute
Add this after you include angular.min.js:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
And then include the dependency in your main app module:
var site = angular.module('site', ['ngRoute']).
Okay, I got it working beyond Antiga's help.
There was few (yet minor) problems. I had to extend templateUrl path to include project folder.
when('/home', {templateUrl: '/ProjectName/pages/home.html', controller: 'mainStaysCtrl'}).
Other thing is that I simply forgot to include $location in controller.
site.controller('mainStaysCtrl', function($scope, $location) {
$scope.setRoute = function(route) {
$location.path(route);
};
});

AngularJS "Controller as" in templates

I am new to AngularJS world and I am trying to setup a basic laravel/angular JWT auth following this tutorial.
What I'd like to do, it's to use the "Controller As" syntax instead of the $scope as stated in the tutorial. For now, here what I have:
app.js
var app = angular.module('app', ['ngRoute']);
app.run(function () {});
app.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: 'js/templates/login.html',
controller: 'LoginController'
});
});
login controller
angular.module('app')
.controller('LoginController', function ($scope) {
this.title='toto';
this.data = {};
this.submit = function () {
console.log(this.data);
};
});
admin view
<!doctype html>
<html lang="en">
<head>
<title>Blog Administration</title>
<!--css-->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"/>
<!--js-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!--angular-->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular-route.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/loginController.js"></script>
</head>
<body ng-app="app">
<div id="wrapper">
<div class="container" id="view" ng-view>
</div>
</div>
</body>
</html>
login template
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-controller="LoginController as login">
<div class="container">
<div id="login" class="col-md-4 col-md-offset-4">
<div id="login-form">
<h4>{{ login.title }}</h4>
<form ng-submit="login.submit()"><!--username-->
<div class="form-group">
<input id="username" type="text" ng-model="login.data.username"/>
</div>
<!--password-->
<div class="form-group">
<input id="password" type="password" ng-model="login.data.password"/>
</div>
<!--submit-->
<div class="form-group">
<button class="btn btn-primary" type="submit">Login</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
The problem is that nothing renders. Is it possible to use a controller per template ?
If I put the <ng-controller="LoginController as login"> directive in the view body instead of template everything renders correctly.
Is it a good practice to define a controller per template ? Because the login template should be as generic as possible, so it can be loaded in any view if the user isn't authenticated, that's why I think putting login() action in the controlelr handling the Admin view is wrong.
Can someone advice me on the best practices to have here ?
In order to use controllerAs syntax with routeProvider you need to declare additional property in route configuration:
$routeProvider.when('/', {
templateUrl: 'js/templates/login.html',
controller: 'LoginController',
controllerAs: 'login'
});
Then you need to clean up login template, removing everything but actual template, e.g. no HTML, body tags, etc. You also don't need extra ngController directive in partial template:
<div id="login" class="col-md-4 col-md-offset-4">
<div id="login-form">
<h4>{{ login.title }}</h4>
<form ng-submit="login.submit()">
<!--username-->
<div class="form-group">
<input id="username" type="text" ng-model="login.data.username" />
</div>
<!--password-->
<div class="form-group">
<input id="password" type="password" ng-model="login.data.password" />
</div>
<!--submit-->
<div class="form-group">
<button class="btn btn-primary" type="submit">Login</button>
</div>
</form>
</div>
</div>
Question 1: Is it possible to use a controller per template ?
Ans: Yes. Its very simply. How, is shown in next answer.
Question 2: Is it a good practice to define a controller per template ?
Ans: As per the AngularJs shown rules, Its good practice. Now see the 2
different way of defining the controller for the template.
a. Directly into the template like: <div ng-controller="myCtrl">Whole template
data goes inside this div.</div>
b. from the app.js where we load the template like this:
.state('app.products.all', {
url: '/all',
templateUrl: 'tpl/products/blocks/thumb.html',
controller: 'ProductsAllCtrl'
})
Here i have also shown the controller with the template path. Second way is
more better then the first.

Using ng-switch to swap templates

I'm trying to switch a "sign in" form for a "sign up" form whenever the user clicks on the "Sign Up" button in my angular app, but at the moment nothing is happening when the button is clicked; The sign in form remains on the screen and there are no console errors. Can anyone tell me where I'm going wrong?
I'm attempting to do this purely in html, is this even possible to achieve?
EDIT: I included a signup function in my UserCtrl which takes care of signing in/ out. Now when I click on sign up the alert is trigger but I get a console error saying TypeError: boolean is not a function.
$scope.signup = function() {
alert('signup function hit');
$scope.signup = true;
}
EDIT 2:
<!DOCTYPE html>
<html ng-app="myApp" >
<head>
<title> My App</title>
<link rel="stylesheet" type="text/css" href="css/app.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" type="text/css" href="css/signin.css">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet"/>
</head>
<body ng-controller="MainCtrl">
<div ng-switch on="view.name">
<div ng-switch-default ng-controller="UserCtrl">
<div ng-show="!isAuthenticated">
<form class = "form-signin">
<div class="control-group">
<img src="img/logo.png">
<br />
<div class="controls">
<br />
<input type="text" ng-model="username" placeholder = "Email Address" >
</div>
<br />
<div class="controls">
<input type="password" ng-model="password" placeholder = "Password" >
</div>
<div class="controls">
<button class = "btn btn-default" ng-click="signIn()">Sign In</button>
<button class = "btn btn-primary" ng-click="view.name = 'signup'">Register</button>
</div>
</div>
</form>
</div>
<div ng-switch-when="signup" ng-controller = "UserNewCtrl" >
<label>
This is where my form should be when my signup button is clicked.
</label>
</div>
//This part of index.html is only shown when a user has been authenticated
<div ng-show="isAuthenticated">
<div class="col-md-2">
//MenuBar code is here
</div>
//Other templates get loaded here
<div class="col-md-10">
<div ng-view></div>
</div>
</div>
</div>
<script src="js/vendor.js"></script>
<script src="js/app.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/jquery-1.10.2.js"></script>
<script src="js/transition.js"></script>
<script src="js/ui-utils.js"></script>
</div>
</body>
</html>
MainCtrl.js:
angular.module('myApp.controllers')
.controller('MainCtrl', function($scope) {
$scope.view={
name: ''
};
})
To achieve your requirement you need a wrapper controller that hold ng-switch on model because ngSwitch creates child scope.
You can design your view like
<body ng-controller="mainCtrl">
<div ng-switch on="view.name">
<div ng-switch-default ng-controller="signInCtrl">
<h1>this is sign in page</h1>
sign in
<br>
go to sign up page
</div>
<div ng-switch-when="signup" ng-controller="signUpCtrl">
<h1>this is sign up page</h1>
sign up
<br>
go to sign in page
</div>
</div>
</body>
Here mainCtrl holds view.name and by default ng-switch-default works means your sign in page, then when you click
go to sign up page
view.name model changed and your sign-up page appear.
Check the Demo
move the app controller to the html tag, then the directive in your body tag should read if you want to match an expression
<html ng-app="myApp">
<body ng-switch="signup">
see here
where signup is a boolean in your myApp scope, that will presumably be changed when the signIn criteria is satisfactory
$rootScope.signup = true;
you can also achieve similar with the ng-show and ng-hide directives

Categories

Resources