I'm new to AngularJS and i don't know whether i'm doing things here right. I have a welcome and a login page. I would like to be able to login on the login page and then be logged on any page of my application. I'm aware that localStorage or cookies would be better than the service to store session data, but i wanted to try this out. When I connect the user using my service in the login partial view, the session variables of the controllers aren't updated. Why?
I guess the issue is quite simple to fix and due to the fact that i missed something.
Thank you in advance for your time.
Harald
Here comes the code:
Template html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>Yahoo 2014 - Welcome</title>
<link rel="icon" type="image/png" href="img/favicon.png">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/animations.css">
<link rel="stylesheet" href="css/template.css">
<script src="lib/jquery/jquery-1.10.2.js"></script>
</head>
<body ng-controller="AppCtrl">
<header>
<nav role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><img src="img/logo.png" alt="Yahoo logo" class="img-responsive navbar-brand"/>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>Groupe</li>
<li>Services</li>
<li>Logiciels</li>
<li>Secteurs</li>
<li>Rejoignez-nous</li>
<li>Investisseurs</li>
<li>English version</li>
<li ng-hide="connected" >Login</li>
<li ng-hide="!connected"> </li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</header>
<div ng-view></div>
{{connected}}
{{username}}
<footer>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<ul class="nav navbar-nav">
<li>Mentions légales</li>
<li>Plan du site</li>
<li>Contacter l'administrateur</li>
</ul>
</div>
</div>
<div class="row">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<p>© Copyright Yahoo 2014</p>
</div>
</div>
</div>
</nav>
</footer>
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
-->
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-route/angular-route.js"></script>
<script src="lib/angular/angular-animate.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="lib/bootstrap/bootstrap.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Index.html partial view
<div id="content">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12"><a id="bannerlink" href="http://www.yahoo.com"><img id="bannerimage" src="img/slider-mobile1.jpg" alt="Banner image" class="img-responsive"></a></div>
</div>
<div class="row">
<div class="articles" ng-repeat="article in articles">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<h3>{{article.title}}</h3>
<p>{{article.content}}</p>
</div>
</div>
</div>
</div>
</div>
Login html partial view:
<div id="content" ng-controller="LoginCtrl">
<form name="login" action="#" ng-submit="login()">
<table>
<tr>
<td>
<p>Nickname</p>
</td>
<td>
<input type="text" name="nickname" ng-model="nickname" required>
</td>
</tr>
<tr>
<td>
<p>Password</p>
</td>
<td>
<input type="password" name="password" ng-model="password" required>
</td>
</tr>
</table>
<input type="submit" id="submit" value="Submit">
</form>
</div>
App.js:
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/index', {templateUrl: 'partials/index.html', controller: 'IndexCtrl'});
$routeProvider.when('/group', {templateUrl: 'partials/group.html', controller: 'GroupCtrl'});
$routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl'});
$routeProvider.otherwise({redirectTo: '/index'});
}]);
Controllers:
'use strict';
/* Controllers */
angular.module('myApp.controllers', [])
.controller('AppCtrl', ['$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.username="Harald";
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
scope.$watch('connected', function(){
alert("Connected changed!");
});
}])
.controller('IndexCtrl', [ '$scope', 'Article', function(scope, Article) {
scope.articles = Article.query();
}])
.controller('GroupCtrl', [function() {
}])
.controller('LoginCtrl', [ '$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
}]);
Services:
'use strict';
/* Services */
// Demonstrate how to register services
// In this case it is a simple value service.
var myAppServices = angular.module('myApp.services', ['ngResource']).
value('version', '0.1');
myAppServices
.factory('Article', ['$resource',
function(resource){
return resource('articles/:articleId.json', {}, {
query: {method:'GET', params:{articleId:'articles'}, isArray:true}
});
}])
.factory('Session', function() {
var connected = false;
var nickname = "unknown";
return{
isConnected : function() {
return connected;
},
getNickname : function() {
return nickname;
},
connect : function() {
connected = true;
window.alert("Connected service!");
},
disconnect : function() {
connected = false;
}
}
});
isConnected() returns a boolean. When you change connected in your service, you assign it a new value, but that won't affect $scope.connected
You could keep the two in sync by using a watch function:
scope.$watch(Session.isConnected, function(connected){
$scope.connected = connected;
});
From what i understand and correct me if i am wrong. you want to store state in a service and check that state when route changes to see if the user is logged in or not without the use of cookies or local storage. However storing user state in just a service will not work as if the user hits refresh button the service will be undefined and no longer valid.
Related
ui-view is not working and there is no error shown. What did I miss? Please help me out and make this work.
This is my index.html which is the main template.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="LoginPage.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
</html>
Here LoginPage.js which I have included in the script tag is the controller for LoginPage.html
app.js is the config file which contains the states.
var Project = angular.module('Project', [ 'ui.router' ]);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login',{
url : '/login',
templateUrl : 'LoginPage.html',
controller : 'LoginCtrl'
})
});
The following is the LoginPage.html which I'm trying to load/render using ui-view in index.html
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50"required>
</div>
</div>
ngRoute and ui.router are different libraries.
You should be importing the right script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
(Instead of /angular-route.js)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
<script type="text/ng-template" id="LoginPage.html">
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50" required>
</div>
</div>
</script>
<script>
var Project = angular.module('Project', ['ui.router']);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: 'LoginPage.html'
})
});
</script>
</body>
</html>
Notice that you also load up ui-router in addition to loading Angular:
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
When creating a link with UI-Router, you will use ui-sref:for example:
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<ul>
<li><a ui-sref="login">login</a></li>
</ul>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
The href will be generated from this and you want this to point to a certain state of your application.
What am I doing wrong? I cannot make it work. The link of login and signin don't react as they are not links. I see the url of the login when I do the mouseover upon the link the following address localhost:8080/demo/index.html#/login. I click but it doesn't work at all.
At the beginning, I didn't realize that I needed to change the anchor attribute href to ui-sref, but when I use href, it redirects to login page completely without the index.html template structure.
html - index.html
<!DOCTYPE html>
<html x-ng-app="demo">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Demo</title>
<link href="../css/bootstrap.css" rel="stylesheet">
<link href="../css/demo.css" rel="stylesheet">
<link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-default" role="navigation" style="margin-bottom: 0px !important;">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header container-fluid">
<a class="navbar-brand" href="index.html">Demo</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a ui-sref="login">Log in</a></li>
<li><a ui-sref="signup">Sign in</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
<!-- /.container -->
<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('images/header.jpg')">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="site-heading" style="height: 250px;">
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1" ui-view="layout">
<!-- THIS IS JUST CONTENT WHEN ARRIVING TO THE INDEX PAGE -->
<div class="post-preview">
<a href="post.html">
<h2 class="post-title">
Title
</h2>
<h3 class="post-subtitle">
blah blah
</h3>
</a>
<p class="post-meta">Posted by Start Bootstrap on September 24, 2014</p>
</div>
<hr>
</div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
</div>
</footer>
<script src="../scripts/jquery-3.1.0.min.js"></script>
<script src="../scripts/angular.min.js"></script>
<script src="../scripts/angular-ui-router.min.js"></script>
<script src="../scripts/bootstrap.min.js"></script>
<script src="../scripts/ui-bootstrap-tpls-2.1.3.min.js"></script>
<script src="../scripts/demo.js"></script>
</body>
</html>
demo.js
var app = angular.module('demo', ['ui.router', 'ui.bootstrap']);
app.config(function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider){
$urlRouterProvider.otherwise('/');
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$stateProvider
.state('index', {
url: '/index',
view:{
'layout': {
templateUrl: 'index.html'
}
},
controller: ''
})
.state('login', {
url: '/login',
view: {
'layout': {
templateUrl: 'login.html'
}
},
controller: ''
})
.state('signup', {
url: '/signup',
view: {
layout: {
templateUrl: 'signup.html'
}
},
controller: 'MyController'
})
});
You're doing it completely wrong.
First of all you need to have at least one ui-view which should be present inside index.html. What's more there won't be any state which is using index.html.
Ok, so here's an example how your index.html should look like:
index.html - navbar-brand destination was changed into ui-sref="home" which is your home/starting page. It's easier to use ui-sref which takes state name (home,login,signup) than href which takes url (#/,#/login,#/singup). Besides you'll have one place to change state destination (url) than searching for all href instances.
<!DOCTYPE html>
<html x-ng-app="demo">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Demo</title>
<link href="../css/bootstrap.css" rel="stylesheet">
<link href="../css/demo.css" rel="stylesheet">
<link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-default" role="navigation" style="margin-bottom: 0px !important;">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header container-fluid">
<a class="navbar-brand" ui-sref="home">Demo</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a ui-sref="login">Log in</a></li>
<li><a ui-sref="signup">Sign in</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
<!-- /.container -->
<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('images/header.jpg')">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="site-heading" style="height: 250px;">
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<!-- a place where your home.html, login.html and signup.html will be included -->
<div ui-view=""></div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
</div>
</footer>
<script src="../scripts/jquery-3.1.0.min.js"></script>
<script src="../scripts/angular.min.js"></script>
<script src="../scripts/angular-ui-router.min.js"></script>
<script src="../scripts/bootstrap.min.js"></script>
<script src="../scripts/ui-bootstrap-tpls-2.1.3.min.js"></script>
<script src="../scripts/demo.js"></script>
</body>
</html>
home.html - template which was previously included inside index.html
<div class="post-preview">
<a href="post.html">
<h2 class="post-title">
Title
</h2>
<h3 class="post-subtitle">
blah blah
</h3>
</a>
<p class="post-meta">Posted by Start Bootstrap on September 24, 2014</p>
</div>
demo.js - here you can find all states definition which are going to be placed in place of ui-view directive.
var app = angular.module('demo', ['ui.router', 'ui.bootstrap']);
app.config(function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider){
$urlRouterProvider.otherwise('/');
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: function(){}
})
.state('login', {
url: '/login',
templateUrl: 'login.html',
controller: function(){}
})
.state('signup', {
url: '/signup',
templateUrl: 'signup.html',
controller: 'MyController'
})
});
I was able to get your code to work when i removed the 'layout' portion. also, i dont think you need the index page in the routing.
<div ui-view></div>
$stateProvider.state('login', {
url: '/login',
templateUrl: 'login.html'
})
.state('signup', {
url: '/signup',
templateUrl: 'signup.html'
})
So I have an application and it's working great (MEAN stack), and I'm adding in the <script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script> and <script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script> so that I can use the modal.
The code will be below, but here are some explanations first. I've added angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']); in my angular app declaration. And then in the controller I properly injected it via locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];. I haven't declared an ng-controlleranywhere in the html, so I'm not really sure what the problem may be.
Lastly, a copy of the error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.5/$injector/unpr?p0=%24modalProvider%20%3C-%20%24modal%20%3C-%20locationDetailCtrl
Below are 4 blocks of code. The first two are locationDetail.controller.js and locationDetail.view.html, the others are the app.js (angular app.js) and index.html.
locationDetail.controller.js
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];
function locationDetailCtrl($routeParams, $modal, loc8rData) {
var vm = this;
vm.locationid = $routeParams.locationid;
loc8rData.locationById(vm.locationid)
.success(function(data) {
vm.data = { location: data };
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
alert("Let's add a review!");
};
}
})();
locationDetail.view.html
<navigation></navigation>
<div class="container">
<page-header content="vm.pageHeader"></page-header>
<div class="row">
<div class="col-xs-12 col-md-9">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p class="rating" rating-stars rating="vm.data.location.rating"></p>
<p>{{ vm.data.location.address }}</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Opening hours</h2>
</div>
<div class="panel-body">
<p ng-repeat="time in vm.data.location.openingTimes" ng-switch on="time.closed">
{{ time.days }} :
<span class="opening-time" ng-switch-when="true">closed</span>
<span class="opening-time" ng-switch-default>{{ time.opening + " - " + time.closing }}</span>
</p>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Facilities</h2>
</div>
<div class="panel-body">
<span class="label label-warning label-facility" ng-repeat="facility in vm.data.location.facilities">
<span class="glyphicon glyphicon-ok"></span>
{{ facility }}
</span>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 location-map">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Location map</h2>
</div>
<div class="panel-body">
<img src="http://maps.googleapis.com/maps/api/staticmap?center={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&zoom=17&size=400x350&sensor=false&markers={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&scale=2" class="img-responsive img-rounded">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary review-panel">
<div class="panel-heading">
<a ng-click="vm.popupReviewForm()" class="btn btn-default pull-right">Add review</a>
<h2 class="panel-title">Customer reviews</h2>
</div>
<div class="panel-body review-container">
<div class="review" ng-repeat="review in vm.data.location.reviews | orderBy:'createdOn':true">
<div class="row">
<div class="well well-sm review-header">
<span class="rating" rating-stars rating="review.rating"></span>
<span class="reviewAuthor">{{ review.author }}</span>
<small class="reviewTimestamp">{{ review.createdOn | date : 'MMMM d yyyy' }}</small>
</div>
<div class="col-xs-12">
<p ng-bind-html="review.reviewText | addHtmlLineBreaks"></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-md-3">
<p class="lead">{{ vm.data.location.name }} is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work done.</p>
<p>If you've been and you like it - or if you don't - please leave a review to help other people just like you.</p>
</div>
</div>
<footer-generic></footer-generic>
</div>
app.js (angular app.js).
(function() {
angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']);
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home/home.view.html',
controller: 'homeCtrl',
controllerAs: 'vm'
})
.when('/about', {
templateUrl: '/common/views/genericText.view.html',
controller: 'aboutCtrl',
controllerAs: 'vm'
})
.when('/location/:locationid', {
templateUrl: '/locationDetail/locationDetail.view.html',
controller: 'locationDetailCtrl',
controllerAs: 'vm'
})
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
}
angular
.module('loc8rApp')
.config(['$routeProvider', '$locationProvider', config]);
})();
index.html
<!DOCTYPE html>
<html ng-app="loc8rApp">
<head>
<meta name="viewport" content="width=device-width", initial-scale="1.0">
<title>Loc8r</title>
<link rel="stylesheet" href="/bootstrap/css/amelia.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css">
<base href="/">
</head>
<body ng-view>
<script src="/angular/angular.min.js"></script>
<script src="/lib/angular-route.min.js"></script>
<script src="/lib/angular-sanitize.min.js"></script>
<script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script>
<script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script>
<script src="/angular/loc8r.min.js"></script>
<script src="/javascripts/jquery-1.12.2.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/javascripts/validation.js"></script>
</body>
</html>
Error tells you there is an unknown provider $modalProvider. That means you are injecting $modal and it isn't defined within the app.
The reason is that angular-ui-bootstrap now uses $uib prefix for services.
Try changing $modal to $uibModal and verify in angular-ui-bootstrap docs
I am new to Angular.js and was trying to create a link that displays a form when clicked on, but it doesn't seem to work.
this my index.html
<!DOCTYPE>
<html ng-app="MyApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div>
<input type="text" ng-model="login.email">
<input type="text" ng-model="login.password">
<button type="button" ng-click="">Login</button>
<a ui-sref="signUp">Create An Account</a>
</div>
</div>
</nav>
<div ui-view></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script src="app.js"></script>
</body>
</html>
This is the form- signup.html*(registration form and takes only email and password)*
<div class="row">
<div class="col-sm-6">
<div class="row">
Email Address
<input type="text" ng-model="newUser.email" class="form-control">
</div>
<div class="row">
Password
<input type="text" ng-model="newUser.password" class="form-control">
</div>
<button ng-click="createUser()">Submit</button>
</div>
</div>
and this is the controller-app.js
<!-- language: lang-js -->
var MyApp = angular.module('MyApp', ['ui.router']);
MyApp.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('signUp', {
url: "/signup",
templateUrl: "signup.html",
})
}
]);
<!-- end snippet -->
the idea is to display the form after the user clicks the 'Create An Account', the ui-router doesnt seem to work even when trying to load any state, could there be anything i am missing or should change or remove?
please and thank you.
I have this index.html which has a navbar in the which is seen on all pages of my single page application. The navbars container div is using the ng-controller="LoginCtrl" value, so I will also include that controller from my angular application (app.js)
For some reason, the variables username and password which are bound via ng-model are showing as undefined when doLogin() is called via ng-click directive? That is after I type values into the text boxes that are bound to my controllers variables.
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="username">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="./app/app.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
</body>
</html>
app.js
...
myApp.controller('LoginCtrl', function($rootScope, $location, AuthService, AuthToken) {
$rootScope.doLogin = function() {
console.log($rootScope.username);
console.log($rootScope.password);
}
});
...
An inputModel primitive property will be created on that ng-controller's scope when you type into the text field. input model is generated in the current scope, not the rootScope.
var app = angular.module('myApp', []);
app.controller('LoginCtrl', function($scope, $http) {
$scope.doLogin = function() {
console.log($scope.username);
console.log($scope.password);
}
});
Check it out on Plunker
Use model rather than using primitive types.
You should use $rootScope.user.name (ng-model will be user.name) rather than using $rootScope.username and $rootScope.user.password(ng-model will be user.password) instead of $rootScope.password
This problem actually happens for javascript's prototypical model. And if you want to know it's applicability in angularjs, you can go through this article. This will definitely help :)
Edit: As you are running into problem making that code work, I've made a working copy of your code. Please have a look at it:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="user.name">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="user.password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
<script>
var myApp = angular.module("myApp", []);
myApp.controller('LoginCtrl', function ($scope, $location) {
$scope.user = { name: "", password: "" };
$scope.doLogin = function () {
console.log($scope.user.name);
console.log($scope.user.password);
}
});
</script>
use $scope instead of $rootScope for getting the ng-model in controller.
I found the answer to my own question after some frustration. Adding username and password arguments to my doLogin() function, then using the directive ng-click="doLogin(user.name, user.pass)" works as I wanted. No clue why it wasn't working the way I was trying, but oh well.