This is a pretty standard question, however I can't seem to find a solution in anything online. Below is the router/index.html page I'm using. I'm not getting any errors in the console, however when the url resolves, correctly, to the login page the entire page is blank. Any ideas, looking at the code below, as to what I'm missing?
router
(function(){
'use strict'
var app = angular.module('app.core');
app.config(AppRouter);
AppRouter.$inject = ['$stateProvider', '$urlRouterProvider'];
function AppRouter($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('main', {
url: '/main',
abstract: true,
resolve:{
Config: 'Config',
config: function(Config){
console.log(Config);
return Config;
}
}
})
.state('main.login', {
url: '/login',
templateUrl: 'app/components/login/login.html',
controller: 'LoginController',
controllerAs: 'vm',
reloadOnSearch: false
})
}
})();
index.html
<div class="slide-animation-container">
<div ui-view id="ng-view" class="slide-animation"></div>
{{scrollTo}}
</div>
login.html
<div class="container" ui-view>
<div class="row vertical-center-row">
<form id="loginForm" class="form-signin" style="max-width:300px;" autocomplete="off" ng-if="attemptLogin">
<h2 class="form-signin-heading" style="font-size:22px">Please Sign In</h2>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span></span>
<input type="text" class="form-control" id="username" placeholder="User Name" ng-model="user.username" required>
</div>
</form>
</div>
</div>
EDIT
The router above resides in my config.js file for my core module:
core.module.js
(function(){
'use strict'
angular.module('app.core', ['angulartics', 'angulartics.google.analytics', 'angulartics.scroll', 'ngRoute', 'ngAnimate', 'ng.deviceDetector', 'ui.router',
'ui.bootstrap', 'ngTable', 'ngSanitize', 'ngCsv', 'toastr', 'angular.chosen', 'rzModule', 'publicServices']);
})();
Your otherwise logic changes the url to /login when no states match.
$urlRouterProvider.otherwise('/login');
However, your state definitions do not have a url that matches /login.
Because main.login is a child of main, it inherits the URL from main.
Therefore, you should use the full URL for main.login in your otherwise() call.
$urlRouterProvider.otherwise('/main/login');
Your module should have injected ui.router as a dependency ,
var app = angular.module('app',['ui.router']);
DEMO
Related
I am trying to navigate to another page by using the selected objectID.
Angular Routing,
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider.when('/',{
controller: 'BooksController',
templateUrl: 'views/books.html'
})
.when('/books/details/:id',{
controller: 'BooksController',
templateUrl: 'views/book_details.html'
})
});
Angular Controller:
var myApp = angular.module('myApp');
myApp.controller('BooksController', ['$scope', '$http', '$location', '$routeParams', function($scope, $http, $location, $routeParams){
console.log('BooksController loaded...');
// This To get request all the books: it works fine
$scope.getBooks = function(){
$http.get('/api/books').then(function(response){
$scope.books = response.data;
});
}
// This to get request a book with specific id it works fine
$scope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
}
}]);
And then I have this html page which work also fine accept the button in the page, this button supposed to give me a clean templateUrl to navigate to another html page but it give me weird URL:
<div class="panel panel-default" ng-init="getBooks()">
<div class="panel-heading">
<h3 class="panel-title">Latest Books</h3>
</div>
<div class="panel-body">
<div class="row">
<div ng-repeat="book in books">
<div class="col-md-6">
<div class="col-md-6">
<h4>{{book.title}}</h4>
<p>{{book.description}}</p>
<a class="btn btn-primary" href="#/books/details/{{book._id}}">View Details</a>
</div>
<div class="col-md-6">
<img class="thumbnail" src="{{book.image_url}}">
</div>
</div>
</div>
</div>
</div>
And once I press the button I'm supposed to get a clean url such as:
http://localhost:3000/#!/books/details/599701c1f3da51117535b9ab
but instead I get this url!
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
Seems like you have hashprefix !, then your URL should also have ! after hash(#)
href="#!/books/details/{{book._id}}"
Since Angular 1.6 hashprefix is defaulted to !, you can disable this behavior by setting hashPrefix to ''(blank).
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('');
}
]);
Its because your url is getting converted into codes. %2f means a /.
You need to have this configuration to avoid this behavior of angular
myApp.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
You have Prefix in url which is converting into character i.e url encoding.
So you need to fix $locationProvider's hashPrefix property by replacing its value with empty/blank string
$locationProvider.hashPrefix('');
So in case it matters, I am using angular in rails. And yes my sprockets is the correct one. So my templates and routes are loading correctly. But my controllers although loading arent being found by ui-router or are being ignored. For a long time i used
ng-controller="mainctrl"
in my app to fix the problem and pushed it aside, but now i need the controller to be loaded in the routes and its not working. So here is my routes file.
app.config(['$stateProvider','$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
// The home routes are at the top of the page.
.state('home', { // This is our navbar, it leads to all of our login screens
url: '/home',
templateUrl: 'home/nav.html',
authenticate: true,
controller: 'AuthCtrl'
})
.state('login', {
url: '/login',
templateUrl: 'home/login.html',
authenticate: false,
contoller: 'AuthCtrl'
// controller: function($scope) {
// $scope.usererror_hide = true;
// $scope.passworderror_hide = true;
// }
})
$urlRouterProvider.otherwise("/login");
Now whats kind of crazy is that if i uncomment that controller:function logic it works. But for some reason it cant find my AuthCtrl. So im not sure if its a rails problem or a routes problem, because they both seem to be functioning.
this is my controller file, though i dont believe its the source of the problem.
var app= angular.module('planoxApp')
app.controller('AuthCtrl',['$http','$scope', '$localStorage', //be careful with the order of http/scope, they get screwey
'$stateParams','$filter','$state','AuthService','$uibModal',
function($http,$scope,$localStorage, $stateParams,$filter,$state,AuthService,$uibModal){
$scope.selectedGlobal = "" //For our future global search, move it to nav
$scope.datas = [] //For global crap, move to nav
//My variable collections that I need access too
$scope.usererror_hide = true;
$scope.passworderror_hide = true;
my application.js file
//=require jquery
//=require jquery_ujs
//=require jquery-ui
//=require jquery-minicolors
//=require tinycolor
//=require bootstrap
//=require angular
//= require angular-route
//=require angular-rails-templates
//require angular-minicolors
//=require angular-animate
//=require angular-bootstrap
//require angular-bootstrap/ui-bootstrap-tpls-0.14.3.js
//=require lodash
//=require angular-resource
//=require holderjs
//=require angular-holderjs
//=require restangular
//=require angular-dragdrop
//=require angular-strap
//=require nya-bootstrap-select
//=require angular-ui-router
//=require angular-ui-router.stateHelper
//=require angular-color-picker
//= require angular-xeditable
//=require angularjs-file-upload
//=require ngstorage
//= require_tree ./templates
// = require_tree .
and my app.js file
planoxApp= angular.module('planoxApp',
['ui.router',
'templates',
'nya.bootstrap.select',
'ngAnimate',
'ui.bootstrap',
'main-directives',
'color.picker',
'xeditable',
'restangular',
'ngDragDrop',
'angularFileUpload',
'ngStorage',
'ngHolder',
'ngResource'
// 'mgcrea.ngStrap',
// 'mgcrea.ngStrap.typeahead',
// 'mgcrea.ngStrap.tooltip',
// 'mgcrea.ngStrap.helpers.parseOptions',
])
Finally the actual html file, which is loading just fine.
<div id="login" >
<div class="container">
<div class="row vertical-offset-100">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-body">
<h1> PlanoX</h1>
<h4> A Catchy Line About PlanoX. </h4>
<form accept-charset="UTF-8" role="form">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="E-mail" name="email" type="text" ng-model="login_username">
<p ng-hide="usererror_hide"> This email is not in our system, please try again or contact planomatic <p>
</div>
<div class="form-group">
<input class="form-control" placeholder="Password" name="password" type="password" value="" ng-model="login_password">
<p ng-hide="passworderror_hide"> This password is not in our system, please try again or contact planomatic <p>
</div>
<div class="checkbox">
<label>
<input name="remember" type="checkbox" value="Remember Me"> Remember Me
</label>
</div>
<input class="btn btn-primary btn-block" type="submit" value="Login" ng-click="CheckUser(login_username, login_password)">
</fieldset>
</form>
<p>© 2015 PlanoX LLC | 888-988-PlanoX (3453) | info#PlanoX.com</p>
</div>
</div>
</div>
</div>
</div>
</div>
If anyone can help me I would really appreciate it, i have been struggling for the past week with this.
-----update-----
So it was just a typo issue, but i wanted to post another problem which i incorrectly though was the same as this one. But turned out to be totally different. This is not the correct way to access a controller in a nested view.
.state('home.index', { // our home page for employee standard
url: '/index',
controller: 'HomeCtrl',
views:{
"":{ templateUrl: 'home/home.html'},
"assembly#home.index":{ templateUrl: 'home/assembly.html'},
"client#home.index":{ templateUrl: 'home/client.html'},
"photoplan#home.index":{ templateUrl: 'home/photoplan.html'}
},
authenticate: true
controller: 'HomeCtrl'
})
This is the correct way to access it.
.state('home.index', { // our home page for employee standard
url: '/index',
controller: 'HomeCtrl',
views:{
"":{ templateUrl: 'home/home.html',
controller: 'HomeCtrl'},
"assembly#home.index":{ templateUrl: 'home/assembly.html'},
"client#home.index":{ templateUrl: 'home/client.html'},
"photoplan#home.index":{ templateUrl: 'home/photoplan.html'}
},
authenticate: true
})
This is just in case in the future anyone sees this question and has a similar problem.
Check the typo when setting the controller:
.state('login', {
url: '/login',
templateUrl: 'home/login.html',
authenticate: false,
controller: 'AuthCtrl'
})
controller
I generate a express project with ejs views engine.
I'm trying to set a templateURL for my home views, but it always feedback a 404 error.
Here are my codes.
In my public/javascripts/angularApp.js
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider){
$stateProvider
.state('home',{
url: '/home',
templateUrl: 'home.html',
controller: 'MainCtrl',
resolve:{
postPromise:['posts', function(posts){
return posts.getAll();
}]
}
})
And in views/index.ejs
<div class="row container">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
In views/home.html
<div class="page-header">
<h1>Flapper News</h1>
</div>
Please help me for this problem.
thanks alot~
This is answered in how-should-i-create-the-path-of-templateurl-property-in-angular-ui-router if using express. Then home.html must be inside the public folder, eg:
public
|--app
|--views
|--home.html
and the route would be:
...
templateUrl: '/app/views/home.html',
...
i have a angular application with phonegap where i have a login form and login controller.
The problem is that the ng-submit doesn't work. Normaly the submit call the fonction formConnexion() but nothing happens. So, i tried with just a alert, but it's the same result...
After i tried with a ng-click and same result. Then, i wanted try to call a sample variable in the scope in the template ($scope.test) and it doesn't display. And the console.log('salut!!') doesn't dispaly when i am on the login page.
Which made me think that my controller it doesn't associate to the template.
But i have the ng-controller in my div with the good name controller.
Then, i thought that angular it's was worse installing but no because the other directives work (ng-if, ng-src, ...)
So, if you have a idea to solve this problem, I do not mind :)
here the code for the template :
login.html
<div class="row jumbotron" style="margin:10px" ng-controller="LoginCtrl">
<div class="col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2 col-sm-8 col-sm-offset-2 col-xs-8 col-xs-offset-2">
<h1>{{ test }}</h1>
<form class="form-horizontal" ng-submit="alert('alert')">
<div class="form-group">
<label for="login" class="control-label">Login</label>
<input type="text" name="login" class="form-control" ng-model="formData.login">
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<input type="password" name="password" class="form-control" ng-model="formData.password">
</div>
<button type="submit" class="btn btn-md btn-success">Connexion</button>
</form>
click
<img ng-src="images/accueil.png" class="accueil img-responsive">
</div>
</div>
and here the controller :
login.js
'use strict';
appStat.controller('LoginCtrl', function ($scope, $rootScope, $http, $location) {
console.log("salut!!");
$scope.formData = {};
$scope.test = "test";
$scope.toto = function() { alert('alert'); };
/**
* Connect l'user
*/
$scope.formConnexion = function () {...}
});
and here my app.js :
app.js
'use strict';
var appStat = angular.module('posStatsPhoneGap', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngMessages',
'ngAnimate',
'ngAria',
'ngTouch',
'picardy.fontawesome'
])
.config(['$routeProvider', '$compileProvider', function ($routeProvider, $compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|tel):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|tel):/);
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/stat', {
templateUrl: 'views/stat.html',
controller: 'StatCtrl'
})
.otherwise({
redirectTo: '/'
});
}
]);
Thank you in advance !
Following from my comment Try something like this:
Create a Controller file & a controller within it Create a angular
module within the controller file
Create a controller.js file then create a angular module see code below:
//Within your controller.js file
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope, $http){
$scope.Data = "Alert Alert";
// Create a function within the scope of the module
$scope.myFunc = function(){
alert($scope.Data)
};
});
Then within your HTML file call the function on-Click see code below:
Note: Don't forget to add the controller you created into your HTML code. I usually add it in the body tag
<body ng-controller="myController">
<button ng-click="myFunc()">Make Request Button</button>
</body>
See a live example here:
http://plnkr.co/edit/sQ0z7TlyWv5fM5XyfujK?p=preview
Also a note: ng-click is mostly used for any click events you are trying to perform within your angular app but ng-submit is mostly used when working with a HTML form submission.
Use ng-submit in you form as:
<form ng-submit="submit()">
function Ctrl($scope) {
$scope.list = [];
$scope.text = 'hello';
$scope.submit = function () {
if ($scope.text) {
$scope.list.push($scope.text);
$scope.text = '';
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit()">Enter text and hit enter:
<input type="text" ng-model="text" name="text" />
<input type="submit" id="submit" value="Submit" /> <pre>list={{list}}</pre>
</form>
<button ng-click="submit()">Submit 2</button>
</div>
</div>
I found the error. It was caused by having 2 controllers with the name 'LoginCtrl'. It was a stupid copy/paste error.
I have created one working code for the above question for 4 different type of HTML element, for complete code please follow the below URL -
http://plnkr.co/edit/Tm2Rtbt3xsv4pKzcPQCw?p=preview
<body ng-controller="ExampleController">
<button ng-click="setButton()">set button</button>
<div content="snippetContentFirst"></div>
<div content="snippetContentSecond"></div>
<div content="snippetContentThird"></div>
<div>
<ul content="snippetContentFour"></ul>
</div>
</body>
I am getting a 404 and cannot figure out why. I know my mongoDB server and node server are working because I can query and view my services. Now I am trying to implement an angular.js frontend on top of the services but I keep getting a 404 when I try to access my "home state".
// Configure the app to use routing. These $ tags are referencing the angular ui-router import.
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// tells your route what controller to use when it gets there
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
});
$stateProvider
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
// .otherwise means "route to this place if the url is anything else" || like an if/else for url routing
$urlRouterProvider.otherwise('home');
}]);
This is some code from app.js that is throwing the code. Standard express generated code here.
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
This is the javscript that should be displaying, which is located in my index.ejs view page in node.
<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 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>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<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">Post</button>
</form>
</script>
Also for reference, my imports on the index.ejs page
<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>
I am baffled by this 404 because I feel like I have a good understanding of this in-line templating routing set up. I have tried everything I can think of and nothing will resolve this 404.
GET /home 404 19.131 ms - 1246
It looks like you made the same mistake I did following this tutorial: you deleted the root route in routes/index.js which is need to serve up the initial index.ejs file. Here it is to add back to your route:
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});