I would like to add new page into default ionic app with tabbed menu and display this page as the default page of the app.
Here is how I tried to do that:
I added new state into app.js
.state('home', {
url: '/home',
views: {
'home': {
templateUrl: 'templates/home.html',
controller: 'HomeCtrl'
}
}
})
and set default router to home page
$urlRouterProvider.otherwise('/home');
And template file:
<ion-view title="Home">
<ion-content class="padding">
<h1>Home page</h1>
</ion-content>
</ion-view>
Now, if I am trying to go to http://myapp.loc/index.html#/home I got always black page without content.
What I'm doing wrong?
Thanks for any help.
EDIT:
In order to Error: [ng:areq] Argument 'HomeCtrl' is not a function, got undefined
I'm adding related code.
Added controllers:
angular.module('starter.controllers', [])
.controller('HomeCtrl', function($scope, $location) {
})
.controller('DashCtrl', function($scope) {
})
.controller('FriendsCtrl', function($scope, Friends) {
$scope.friends = Friends.all();
})
.controller('FriendDetailCtrl', function($scope, $stateParams, Friends) {
$scope.friend = Friends.get($stateParams.friendId);
});
Order in index.html is following
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/controllers/overall_stats.js"></script>
<script src="js/services.js"></script>
I would say, that solution here should be surprisingly simple:
Remove the view name 'home'. In fact change it to '' (empty string)
There is a working plunker with this change?
.state('home', {
url: '/home',
views: {
// instead of this
// 'home': {
// use this
'': {
templateUrl: 'tpl.home.html',
controller: 'HomeCtrl',
}
}
})
Why? Because most likely the index.html would look like this:
<body ng-app="myApp" >
...
<ion-nav-view></ion-nav-view>
</body>
And that means that the view name is "", almost like <ion-nav-view name=""></ion-nav-view>
Check that in action here
EXTEND based on the question extension
if we use ionic-like approach with separated file and module for controllers:
// inside of the index.html
<script src="js/controllers.js"></script>
// the controller.js
angular.module('starter.controllers', [])
We must be sure, that our app.js does contain that module as well:
angular.module('myApp', [
'ionic',
'starter.controllers' // this is a MUST
])
Related
I am making a web app using Angular for front-end.
If user whose role is teacher trying to access applicant's portal, I want to block them by showing 404.html template. I do not want to redirect the users to www.example.com/404 but rather just let them stay at where they are at www.example.com/teacher but render 404.html template.
I am not sure how I can achieve this using ngroute. Here is the code what I have in app.js:
app.config(['$routeProvider', '$locationProvider', 'CookieProvider',
function ($routeProvider, $locationProvider, CookieProvider) {
var cookieData = CookieProvider.$get().getCookieData();
$routeProvider.when('/applicant', {
templateUrl: '/front-end/public/views/Prescreening/review.html',
controller: 'ReviewCtrl',
resolve:{
"check":function($location, CookieService) {
var cookieData = CookieService.get();
if(cookieData["user_role"] == 'teacher'){
$location.path('/404')
}
}
}
}).when('/404', {
templateUrl: '/404.html'
}).otherwise({
templateUrl: '/404.html'
});
}]);
How can I render 404.thml without redirecting the user to /404 ?
Let's say you have a state like this.
.state('dashboard.users', {
url: '/users/:isAdmin',
templateUrl: 'modules/dashboard/templates/users.html',
controller: 'usersController',
})
Try this.
angular.module(...)
.config( ['$routeProvider', function($routeProvider) {...}] )
.run(function($rootScope, $location) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
// You can pass the user role to the params
// of the state and you will see that on the
// toParams call callback ex. {isAdmin:false}
if(!toParams.isAmin){
toState.templateUrl = "modules/404/templates/404.html";
}
});
})
})
UPDATE
The callback toState actually contains the following
url = url of the current state ex. /user
templateUrl = path to the template ex. path/to/something.html
controller = the controller name of the state ex. usersController
name = the state name ex. dashboard.user
When this line gets executed toState.templateUrl = "modules/404/templates/404.html"; The current template of your state which falls under the <div ui-view></div> will have the 404.html that you desire.
IMPORTANT
You must use ui.router and not ngRouter to make this implementation work.
After some efforts I got it working... Here are the different codes...
I have used bower so please replace with your paths..
Here is the plunk.. I got it working..
https://plnkr.co/edit/dK7n6PmhldJ1p0plWPp2?p=preview
index.js
var app = angular.module('myApp',['ngRoute']);
app.config(['$routeProvider',function ($routeProvider) {
$routeProvider
.when('/applicant', {
template: 'Applicant!',
controller: function($scope){
alert("Applicant Controller");
}
})
.when('/404', {
templateUrl: '404'
})
.otherwise({
templateUrl : '404.html'
});
}]);
index.html
<html>
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src = "index.js"></script>
</head>
<body ng-app="myApp">
<ng-view></ng-view>
</body>
</html>
404.html
<h1>404 page</h1>
I have an AngularJS application. I recently added couple of routes but they don't work. The rest is working fine.
I included them in my index.html
<script src="privacy_policy/privacy_policy.js"></script>
<script src="contacts/contacts.js"></script>
I added them in my app.js file:
angular.module('myApp', [
...
'myApp.privacy_policy',
'myApp.contacts',
...
]).
The route system:
$routeProvider.when('/privacy_policy', {
templateurl: 'privacy_policy/privacy_policy.html',
data: {
needauth: false
}
});
$routeProvider.when('/contacts', {
templateurl: 'contacts/contacts.html',
data: {
needauth: false
}
});
I added a simple controller:
'use strict';
angular.module(
'myApp.privacy_policy', ['ngRoute']
).
config(['$routeProvider', function($routeProvider) {
}]).
controller('PrivacyPolicyCtrl', ["$scope", "$http", "store", "URL", function($scope, $http, store, URL) {
}]);
And some simple html:
<div ng-controller="PrivacyPolicyCtrl" class='row below-header'>
PRIVACY POLICY
</div>
Finally I created a simple link to that view:
<li><a href='/privacy_policy'>Privacy policy</a></li>
I created the SAME things for contacts but if I click on those link ng-view is completely empty.
All the others route are working fine and I can't see any difference. I get no error on the console.
In the route system in app.js If I put a different template, for example:
$routeProvider.when('/privacy_policy', {
templateurl: 'faq/faq.html',
data: {
needauth: false
}
});
The faq page is diplayed correctly. What am I missing?
Ok I finally find you what the problem is.
I only needed to change this:
templateurl: 'contacts/contacts.html',
with this:
templateUrl: 'contacts/contacts.html',
In my angular project the user accepts a EULA then get automatically redirected to their dashboard, however, on this redirect the DashboardController seems to be being called twice, the DashboardController is being called on the route itself, I have checked to see if I have accidently called it again in the template but I havn't. Below is my route & controller. It doesn't appear to matter if I access the URL directly or via the redirect on the EULA controller, I get the same result.
The routes
.config(function($httpProvider, $stateProvider, $urlRouterProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url: '/',
templateUrl: 'templates/login.html',
data: {
requireLogin: false
}
})
.state('eula', {
url: '/eula',
templateUrl: 'templates/eula.html',
data: {
requireLogin: true
}
})
.state('dashboard', {
url: '/groups',
templateUrl: 'templates/dashboard.html',
data: {
requireLogin: true
}
})
});
The controller:
App.controller('DashboardController', ['$scope', 'RequestService', '$state', '$rootScope', function($scope, RequestService, $state, $rootScope){
alert('test');
}]);
Any ideas?
ADDED MY HTML AS PER COMMENTS
index.html
<body ng-app="App">
<ion-nav-bar class="bar-positive nav-title-slide-ios7" align-title="center">
<ion-nav-back-button class="button-icon ion-arrow-left-c"></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view class="slide-left-right"></ion-nav-view>
<ui-view></ui-view>
</body>
dashboard.html
<div class="groups" ng-controller="DashboardController">
<ion-view title="App">
<ion-nav-buttons side="right">
<a ui-sref="groupcreate"><span class="icon ion-ios-plus-outline"></span></a>
</ion-nav-buttons>
<ion-content class="padding">
<div class="row">
<div class="col-50" ng-repeat="group in groups">
{{ group }} 1
</div>
</div>
</ion-content>
</ion-view>
</div>
If you are using ui-router you don't have to use ng-controller. You have used it in your dashboard.html, another is generated by ui-router - that's why it is hit twice.
Ok so after a long time debugging and check stuff out, I found out that it was an issue relating to the Nav Bar in ionic, essentially, I was calling <ui-view></ui-view> & <ion-nav-view></ion-nav-view> on the same page, so basically doubling up on my views which in turn was calling the controller twice.
I know this has been answered already as well, but I wanted to add my fix for the exact same problem.
My controllers were also being called twice, but in my case I had to comment out the ng-controller settings in various files:
My config function in the main app.js
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('splash', {
url: "/",
templateUrl: "app/splash/splash.html"
// controller: 'SplashCtrl'
})
Since I was already calling it in the markup:
<ion-view view-title="TickerTags" ng-controller="SplashCtrl as splash">
<ion-content class="splash">
The controller key inside of my Directives
angular
.module('tagsPanelDirective', [])
.controller('TagsPanelCtrl', TagsPanelCtrl)
.directive('tagsPanel', tagsPanel);
function tagsPanel() {
var directive = {
templateUrl: "app/tags/tagsPanel.html",
restrict: "E",
replace: true,
bindToController: true,
// controller: 'TagsPanelCtrl as tagsPanel',
link: link,
scope: false
};
return directive;
function link(scope, element, attrs) {}
}
Again since I was already calling it from within the template markup:
<section class="tags-panel" ng-controller="TagsPanelCtrl as tagsPanel">
As I felt my single controller was growing too large I am now trying to make use of multiple controllers. However, my UserController can't be found for some reason when I navigate to /signup. I'm getting this error:
Error: [ng:areq] Argument 'UserController' is not a function, got undefined
app.js
var app = angular.module('myApp', [
'ui.router',
'ngResource',
'myApp.controllers',
]);
angular.module('myApp.controllers', []);
app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('signup', {
url: '/signup',
templateUrl: 'views/signup.html',
controller: "UserController"
});
});
I'm including the .js files in this order:
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state
<script src="angular/app.js"></script>
UserController
angular.module('myApp.controllers').controller('UserController', function () {
//do stuff
});
What am I missing?
Make it easier on yourself and create cleaner code.
var app = angular.module('myApp', [
'ui.router',
'ngResource',
'myApp.controllers',
])
.config(function($stateProvider) {
$stateProvider
.state('signup', {
url: '/signup',
templateUrl: 'views/signup.html',
controller: "UserController"
});
});
you weren't using $urlRoutProvider and $httpProvider so why inject them?
Angular Modules are good for nothing...so far. Except for loading 3rd-party angular code into your app and mocking during testing. Other than that, there is no reason to use more than one module in your app.
To create your UserController do a
app.controller('UserController', function ($scope) {
//do stuff
});
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state
<script src="angular/app.js"></script>
You cant use a module before it's declared.so switch the scripts order.
You should stick to 1 independent module declaration per file and you'll be fine,otherwise you'll have to manage script order.
Your app.js has to be declared first like below BEFORE you pull in its controller subcomponents:
<script src="angular/app.js"></script>
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state
I'm really new to Angular and I have a little question about sending a template or URL into a ng-view. But the way I intend to do I may have to ng-view in my base template.
When my template base is like this:
<body>
<div ng-view></div>
</body>
And my JS looks like:
var app = angular.module('myApp',[])
.config(['$routeProvider', '$locationProvider', '$httpProvider', function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.when('/home', {
templateUrl: '/contato'
})
(...)
Works fine loading URL inside ng-view when I have only ONE ng-view case, HOW ABOUT IF I need to have more then one ng-view to load ? (like: ng-view="area1" and ng-view="area2")
I've tried in each $routeProvider, but won't work:
$routeProvider
.when('/home', {
area1: {templateUrl: '/path1'},
area2: {templateUrl: '/path2'}
})
How would be the right way to set each ng-view separately?
Appreciate any help! Thanks.
Unfortunately, as you know now, you cannot have more than one ng-view on your page. You should have a look at UI-Router from AngularUI which does exactly what you are looking for (https://github.com/angular-ui/ui-router).
An example from their doc (https://github.com/angular-ui/ui-router#multiple--named-views):
setup
var myApp = angular.module('myApp', ['ui.router']);
html
<body>
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
<!-- Also a way to navigate -->
<a ui-sref="route1">Route 1</a>
<a ui-sref="route2">Route 2</a>
</body>
template 1
<h1>State 1</h1>
template 2
<h1>State 2</h1>
js
myApp.config(function($stateProvider, $routeProvider) {
$stateProvider
.state('index', {
url: "",
views: {
"viewA": { template: "index.viewA" },
"viewB": { template: "index.viewB" }
}
})
.state('route1', {
url: "/route1",
views: {
"viewA": { templateUrl: "route1.viewA.html" },
"viewB": { templateUrl: "route1.viewB.html" }
}
})
.state('route2', {
url: "/route2",
views: {
"viewA": { templateUrl: "route2.viewA.html" },
"viewB": { templateUrl: "route2.viewB.html" }
}
});
});
Here you could specify a controller at the state level, that would be effective for both views, or at the view level, in order to set two different controllers.
Edit: Live demo from ui-router docs (http://plnkr.co/edit/SDOcGS?p=preview)
Basically you can't have two ng-view. Have a look at this SO question:
You can have just one ng-view.
You can change its content in several ways: ng-include, ng-switch or mapping different controllers and templates through the routeProvider.