How to use ui-sref in ui-router AngularJS - javascript

i have file index.html:
<!DOCTYPE html>
<html>
<head>
<style>
.navbar { border-radius:0; }
</style>
<link rel="stylesheet" type="text/css" href="lib/css/bootstrap.min.css">
<script src="./node_modules/angular/angular.js"></script>
<script src="./node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
<script src="./node_modules/angular-ui-router/release/angular-ui-router.js"></script>
<script src="lib/js/app.js"></script>
</head>
<body ng-app="nav-module">
<a ui-view="home" ui-sref="home" ui-sref-active="active">home</a>
<a ui-view="about" ui-sref="about" ui-sref-active="active">about</a>
<ui-view>
</ui-view>
</body>
</html>
and file app.js:
var app = angular.module("nav-module", ["ui.router",'ui.bootstrap']);
app.component('navComponent',{
templateUrl: './navbar.component.html'
});
app.config(['$stateProvider',
'$urlRouterProvider',function($stateProvider,$urlRouterProvider) {
$stateProvider
.state('/home',{
name: 'home page',
url:'/home',
template: '<h3>hello world!</h3>'
})
.state('/about',{
url:'/about',
component: 'navComponent'
});
$urlRouterProvider.otherwise('/home');
}]);
and nav-bar.component.html:
<h1>nav bar</h1>
but i can't click to tag to run page, and when i change /about in URL, the console show error:
Failed to load template: ./navbar.component.html
i dont know why.

I think you're missing the templateurl location or file name as you mention that your
templateUrl:'./navbar.component.html' but your file name is nav-bar.component.html.
First remove templateUrl & check it by using template: <h1>nav bar</h1> in component.
If it's OK,then your error is for just missing the templateUrl refrence or the file name.
Then fix this by using ../app/navtemplateurl.html and file name is navtemplateurl.html which is inside the app folder.
Adding 'ui.bootstrap.tpls' in your module can also solve this problem
Update: ust change the angularui router refrence from index file to <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.0-rc.1/angular-ui-router.js"></script> as component templates in ui-router are not supported in v0.4.2 or earlier.
You also need to update this.

Related

Can not get grandchild state to work with UI Router

I am using Angular 1.6.2 and UI Router. I am still trying to learn the concepts correctly, but have come to a road block.
I have a parent state called app using MainController, and a bunch of child states. However I now want to go one level deeper by making grandchild states.
The following codes leaves me with a blank page when loading www.example.com/manage-users/edit/1 thus not loading the grandparent state.
However it does work if I make app a parent of edit-users (the one I want to make a third level deep), but thats not really the correct way of going about it. Because after this I need to use the parent states for other reasons.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
// loading JS/CSS etc
</head>
<body ng-app="sampleApp">
<div class="container">
<div ui-view></div>
</div>
</body>
</html>
parent.html
<div ng-controller="MainController as data">
// more html
<div ui-view></div>
</div>
manage-users.html
<div class="col-sm-12" ng-controller="UserController as data">
// more html
<div ui-view></div>
</div>
manage-users-edit.html (only works when I make the parent state 'app' instead of 'manage-users'
<div>Hello World! This is the Edit HTML Page</div>
app.js setting up states
$stateProvider
.state('app', {
templateUrl: 'views/parent.html',
controller: 'MainController as data'
})
.state('manage-users', {
parent: 'app',
url: '/manage-users',
templateUrl: 'views/manage-users.html',
controller: 'MainController as main'
})
.state('edit-users', {
parent: 'manage-users',
url: '/manage-users/edit/:id',
templateUrl: 'views/manage-users-edit.html',
controller: 'MainController as main'
});
Try this:
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
// loading JS/CSS etc
</head>
<body ng-app="sampleApp">
<div class="container" ui-view="container"></div>
</body>
</html>
parent.html
<div ng-controller="MainController as data">
// more html
<div ui-view="parent"></div>
</div>
manage-users.html
<div class="col-sm-12" ng-controller="UserController as data">
// more html
<div ui-view="manageusers"></div>
</div>
app.js
$stateProvider
.state('app', {
views:{
'container': {
templateUrl: 'views/parent.html',
controller: 'MainController as data'
}
}
})
.state('app.manage-users', {
url: '/manage-users',
views:{
'parent':{
templateUrl: 'views/manage-users.html',
controller: 'MainController as main'
}
}
})
.state('app.manage-users.edit-users', {
url: '/edit/:id',
views:{
'manageusers':{
templateUrl: 'views/manage-users-edit.html',
controller: 'MainController as main'
}
}
});
You should always navigate to the child of your hierarchy. In this case, $state.go('app.manage-users.edit-users')
EDIT:
Your URL property in state config is wrong. To hit what you expect, you should enter http://exapmle.com/#/manage-users/edit/1.
I have updated the config, so extra manage-users from the URL is removed. Give it a shot.

Angular ng-href doesn't work

I am using Chrome and have set up node server that is listening on port 8080 and provides all listed files. Angular app.js suppose to show the content of StuffView.html (simple text).
index.html :
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<title>angular</title>
<link rel="icon" href="">
<link rel='stylesheet' href="css/style.css">
<script src="libs/angular/angular.js"></script>
<script src="libs/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="js/controllers/StuffController.js"></script>
</head>
<body>
<div>
<a ng-href = "#/stuff"> show stuff </a>
<ng-view></ng-view>
</div>
</body>
</html>
app.js:
angular
.module( 'app', [ 'ngRoute' ] )
.config( function( $routeProvider ) {
$routeProvider.when( '/stuff', {
templateUrl : "views/StuffView.html",
controller : "stuffController"
} );
} );
StuffView.html:
<H1>Hello from Stuff View! {{hello}}</H1>
where {{hello}} comes from stuffController :
angular
.module( 'app' )
.controller( 'stuffController', stuffController );
function stuffController( $scope ) {
$scope.hello = 'Hello from stuffController! ';
}
When I click the link, the address in browser changes to http://localhost:8080/#!#%2Fstuff and nothing gets displayed.
No errors in the console. What am I missing?
please refer to this link for ngRoute module use.
Do not use 'ng-href' directory in your static case, instead try:
show stuff
I think you have used ng-href in wrong way see the angular documentation for ng-href for the same.
https://docs.angularjs.org/api/ng/directive/ngHref
You should create a variable called path for pathforstuffand then use that variable like below.
var pathforstuff="stuff";
<a ng-href="#/{{pathforstuff}}"/>Take Me Somewhere</a>

Login page with different css and js files

I'm new to angularjs and just started working on a project
I'm using ui.router for managing different views
the problem im facing is that i have a master page index.html for example
<html lang="en" ng-app="leadsangularApp">
<head>
<link href="style1.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div ui-view=""></div>
</body>
</html>
all my views load in
<div ui-view=""></div>
but what if i have a login page that has completely different css styles(head) and js files(footer) i need it to load inside different template, example
<html lang="en" ng-app="leadsangularApp">
<head>
<link href="style2.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div ui-view=""></div>
</body>
</html>
if i try to do it with nested ui-view
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
// States
$stateProvider
.state('root', {
abstract: true,
templateUrl: 'views/default.html',
})
.state('home', {
parent: "root",
url: "/home",
templateUrl: 'views/main.html',
})
.state('login', {
url: "/login",
templateUrl: 'views/login.html',
});
});
my /login page has different view but still it loads the same css and js files
i want my /login page to have completely different head section and footer section, how do i achieve that?
Generally speaking this is not a recommended approach, but there is a github project that does this for css: https://github.com/manuelmazzuola/angular-ui-router-styles. It's not something directly supported by ui-router.
You can use ng-href. And depending on your needs, you will have to listen to $stateChangeSuccess and change the values that is binded to ng-href.
For your HTML, do something like this:
<link rel="stylesheet" ng-href="{{stylesheet}}" />
where the variable stylesheet is dynamically binded to your scope, and can change values according to your needs.
Then you can either listen to $stateChangeStart or $stateChangeSuccess and change the $scope.stylesheet values accordingly.
app.controller('mainCtrl', function($scope, $state) {
$scope.stylesheet = "style.css";
$scope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
if (toState.name === "login") {
$scope.stylesheet = "style2.css"
} else {
$scope.stylesheet = "style.css"
}
})
})
Here is the plnkr: http://plnkr.co/edit/qR7FLDAyRTkFndMQyWod?p=preview
To read more about ui-router's API: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state

NgRoute not loading (modulerr error)

I'm going through Scotch.io's MEAN Machine book, and I'm nearly done. Problem is I can't get my Angular code to run correctly——even when I'm literally copying the code from their Github. Whenever I open my app on localhost, ngRoute fails to load (or be injected or whatever) correctly.
Here is my code:
App.js
angular.module('userApp', ['ngAnimate', 'app.routes', 'authService', 'mainCtrl', 'userCtrl', 'userService'])
]);
App.routes
angular.module('app.routes', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
//home page route
.when('/', {
templateUrl : 'app/views/pages/home.html'
})
//route for the login page
.when('/login', {
templateUrl : 'app/views/pages/login.html',
controller : 'mainController',
controllerAs : 'login'
});
//get rid of the hash in the URL (url prettification)
$locationProvider.html5Mode(true);
});
mainCtrl.js
angular.module('mainCtrl', [])
.controller('mainController', function($rootScope, $location, Auth) {
var vm = this;
//get user info if logged in
vm.loggedIn = Auth.isLoggedIn();
//check to see if user is logged in ON EVERY REQUEST
$rootScope.$on('$routeChangeStart', function() {
vm.loggedIn = Auth.isLoggedIn();
//get user information on route change
Auth.getUser()
.success(function(data) {
vm.user = data;
});
});
//this function handles the login form
vm.doLogin = function() {
vm.processing = true;
//call the Auth.login() function
Auth.login(vm.loginData.userName, vm.loginData.password)
.success(function(data) {
vm.processing = false;
//if user is logged in, redirect to user page
$location.path('/users');
});
};
//function to handle logging out
vm.doLogout = function() {
Auth.logout();
//reset ALL user info
vm.user = {};
$location.path('/login');
};
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User CRM</title>
<!-- FOR ANGULAR ROUTING -->
<base href="/">
<!-- CSS -->
<!-- load bootstrap from CDN and custom CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.1/paper/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<!-- JS -->
<!-- load angular and angular-route via CDN -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.js"></script>
<!-- controllers -->
<script src="app/controllers/mainCtrl.js"></script>
<script src="app/controllers/userCtrl.js"></script>
<!-- services -->
<script src="app/services/authService.js"></script>
<script src="app/services/userService.js"></script>
<!-- main Angular app files -->
<script src="app/app.routes.js"></script>
<script src="app/app.js"></script>
</head>
<body ng-app="userApp" ng-controller="mainController as main">
<!-- NAVBAR -->
<header>
<div class="navbar navbar-inverse" ng-if="main.loggedIn">
<div class="container">
<div class="navbar-header">
<span class="glyphicon glyphicon-fire text-danger"></span> User CRM
</div>
<ul class="nav navbar-nav">
<li><span class="glyphicon glyphicon-user"></span> Users</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li ng-if="!main.loggedIn">Login</li>
<li ng-if="main.loggedIn" class="navbar-text">Hello {{ main.user.username }}!</li>
<li ng-if="main.loggedIn">Logout</li>
</ul>
</div>
</div>
</header>
<main class="container">
<!-- ANGULAR VIEWS -->
<div ng-view></div>
</main>
</body>
</html>
This is the exact error I'm receiving:
https://docs.angularjs.org/error/$injector/modulerr?p0=userApp&p1=Error: [$injector:nomod] http://errors.angularjs.org/1.3.8/$injector/nomod?p0=userApp
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:6:416
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:366
at a (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:7)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:250
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:35:424
at s (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:7:302)
at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:35:202)
at Ob (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:38:435)
at d (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:17:350
Remove 'userCtrl' from the dependencies in the userApp module in app.js. You may have created that file, but there probably isn't any content. This should do the trick.
I ran into the same problem, the 'userService' dependency in app.js isn't loaded in the index.html file.
To fix this issue add the userService.js file in your index.html file underneath the authService.js file like so:
<!-- services -->
<script src="app/services/authService.js"></script>
<script src="app/services/userService.js"></script>
In your index.html => <body ng-app="userApp" so you need add to your mainCtrl.js look like this:
angular.module('userApp.mainCtrl', [])
You also need do the same way to userCtrl.js, authService.js, userService.js and app.routes.js.
Now in your App.js finally may look like this:
angular.module('userApp', ['ngAnimate', 'userApp.Routes', 'userApp.authService', 'userApp.mainCtrl', 'userApp.userCtrl', 'userApp.userService'])
]);
Edit
I try your code in plunker but with commenting <base href="/"> and change
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
for it work in plunker. Here (http://embed.plnkr.co/BHyE6iWDN5uXqiitaMDU/preview) you can visit it with same error in console log. It's seem due to fail load some depedencies which i left empty at some file.
Here (http://embed.plnkr.co/eD4TYgMNq4MDHQZ7p3n0/preview) another plunker that you can see the error has gone, all of depedencies success loaded. Make sure you have correct typo & not missing the depedencies.

ui-router nested views and passing variable

i have a lot of question about the angular ui-router module.
I'm tryin to understand it well before implement my applications with that one, but i have problems even with simple things.
HTML
<!doctype>
<html ng-app='myapp'>
<head>
<title>main</title>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<!--controller-->
<script src="app.js"></script>
<script src="controller.js"></script>
<!-- endbuild -->
</head>
<body>
hi
<div ui-view="view1"></div>
<div ui-view="view2"></div>
</body>
</html>
EDIT
var app=angular.module('myapp',['ui.router'
]);
app.config(function($stateProvider/*,$urlRouteProvider*/){
//$urlRouteProvider.otherwise("view1");
$stateProvider.
state('father',{
abstract:true,
template:'<div ui-view></div>',
controller:function($scope){
$scope.view='hi';
}
}).
state('son',{
parent:'father',
url:'/',
views:{'view1':{
templateUrl:'view1.html'
},
'view2':{
templateUrl:'view2.html'
}
}
})
})
and this is my js plunker http://plnkr.co/edit/hsEFKhpaGkIkzarQiuQQ?p=preview.
Now the questions:
1) As you can see in the index.html nothing appears, and my first intention is to see both the views in the main window
2)i have build an abstract state to pass a $scope.view to all the child state, but it seems it didn't work too
3)If what i want to do is done in the wrong way, what's the better approach to do it?
After spending more time than I should have playing around with it, I think I figured out what you were looking for.
I made a few changes and I will try to go over them all.
In the HTML, I added ui-router, moved your js script tags to just before </body>, that allowed me to get rid of all the console errors:
<!doctype>
<html ng-app='myapp'>
<head>
<title>main</title>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ui-view ></div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<script src="ui-router.js"></script>
<script src="app.js"></script>
</body>
</html>
Than in your app.js file I made a few changes:
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('', '/');
$stateProvider
.state('father', {
abstract: true,
// I couldn't get this to work without a templateUrl for some reason,
// I'm sure with a little time you could figure this part out.
templateUrl: 'father.html',
controller: function($scope) {
$scope.view = 'Hello Dad';
console.log($scope.view);
}
})
.state('father.son', {
parent: 'father',
url: '/',
views: {
// Added the absolute target declaration `#father`, see link 1 below
'view1#father': {
templateUrl: 'view1.html',
controller: function($scope) {
console.log($scope.view);
}
},
'view2#father': {
templateUrl: 'view2.html',
controller: function($scope) {
console.log($scope.view);
}
}
}
})
});
Here is the father.html template:
<!-- Big file, I know -->
<div ui-view="view1"></div>
<div ui-view="view2"></div>
Link 1: View Names - Relative vs. Absolute Names
Link 2: Plunker

Categories

Resources