Load different templates and controllers in routes in Angular? - javascript

My app.js file looks like so:
angular.module('airline', ['ngRoute', 'airlineServices', 'ngCookies'])
.config(airlineRouter);
function airlineRouter($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'partials/destinations.html',
controller: 'DestinationsCtrl'
})
.when('/airports/:airportCode', {
templateUrl: 'partials/airport.html',
controller: 'AirportCtrl'
})
.when('/airports/:airport1/:airport2', {
templateUrl: 'partials/two_airports.html',
controller: 'TwoAirportsCtrl'
})
.when('/flights', {
templateUrl: 'partials/flights.html',
controller: 'FlightsCtrl'
})
.when('/reservations', {
templateUrl: 'partials/reservations.html',
controller: 'ReservationsCtrl'
})
.otherwise({
redirectTo: '/'
});
};
Now I simply wish that if the user is logged in, which I can easily try by sending a token from cookies to the server and getting a response, I wish to load a view and a controller, but if the user is not logged in, I just wish to load the login view and the login controller? How can configure the '/' route so that it loads different views and controllers?

The views are going to load dynamically, so you do not need to worry about them. The controller is part of your setup, so again, you do not need to worry about them.
What you want to do is to display a view based on whether the user is authenticated or not.
When the user authenticates you want to setup a property somewhere, possibly in the $rootScope and then you can show different views, a code similar to below:
<div data-ng-if="application.isAuthenticated()">
<div>
I am logged in
</div>
</div>
<div data-ng-if="!application.isAuthenticated()">
hello anon, please login.
<button class="btn btn-primary" ng-click="application.login()">Login</button>
</div>

Related

Angularjs routes are coming upto localhost only

I have to setup a wordpress site which was developed by another team locally. They used angularjs. I am very new to angular. I placed the wordpress files in wamp server. The name of the folder is playbook.
When I tried to access the site by using url localhost/playbook, I got a javascript error saying localhost/home not found.
I checked the javascript file and I saw routing like this
.when('/', {
controller: 'HomeCtrl',
templateUrl: '/home'
})
When I added /playbook at the start like below of templateUrl, page displayed
.when('/', {
controller: 'HomeCtrl',
templateUrl: '/playbook/home'
})
Why is this happening. Shouldn't the route take the path up to localhost/playbook?
You need to specify the extension .html for the template.Assuming your file is called home.html, replace your current code with
.when('/', {
controller: 'HomeCtrl',
templateUrl: '/playbook/home.html'
})
Regarding the usage of a more specific path.Consider this, you are coding a multi-module app in Angular.To seperate concerns, you may have a file structure that is based on each module.So my routes could look something like this. For my file, this was defined in app.js , which was inside the JS folder in my whole application.Additionally, you may choose to define routes in a seperate folder altogether. There is no reason for it to default to a particular file or folder.
foodApp.config(['$routeProvider',function($routeProvider){
$routeProvider.when('/',
{
templateUrl:'js/apps/choiceScreen/choice.html',
controller:'choiceCtrl'
})
.when('/cafe',
{
templateUrl:'js/apps/cafe/cafeScreen.html',
controller:'cafeCtrl'
})
.when('/showCafe/',
{
templateUrl:'js/apps/eachScreen/itemView.html',
controller:'itemCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);

Access variable from router in Angular

I am working on a web application with Angular. I have created a header that is included in the index.html, so it is fixed to every page and the content of the page is injected through a ui-view. My question is: if I want to only show this header after the user has passed the signup and login pages, what should I do?
I have added a variable to my router as shown below, but I am not sure how to access the router's variable from the index.html, as it is not attached to a controller (since it is fixed content across all pages). I intended to simply throw an ng-hide="hideHeader" in the index.html.
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/views/login/login.html',
controller: 'loginController',
controllerAs: 'vm',
hideHeader: true
})
.state('signup', {
url: '/signup',
templateUrl: 'app/views/signup/signup.html',
controller: 'signupController',
controllerAs: 'vm',
hideHeader: true
})
.state('landing', {
url: '/landing',
templateUrl: 'app/views/landing/landing.html',
controller: 'landingController',
controllerAs: 'vm',
hideHeader: false
})
.state('account-management', {
url: '/account-management',
templateUrl: 'app/views/account-management/account-management.html',
controller: 'accountManagementController',
controllerAs: 'vm'
hideHeader: false
});
});
How can I access this hideHeader value from the index.html? Is there a way to set a global scope variable and get the value from there?
Here's a different approach: Create a service specifically for authentication (login/logout) and authentication status. Then just call that service in your header. Given that the header is dependent on your authentication, then it makes sense to abstract that away. Your login/signup controllers will interact with this service.
Your routes can now also call this service to see if they should allow the user to view them based on login status.

AngularJS: Hide Sidebar in Login (and Signup) view

I need a sidebar in an Angular app. The sidebar should be present in every views but one, the login view (and probably others, like signup).
At the moment, the sidebar its a view, included in index.html:
<div ng-include src="'assets/partials/sidebar.html'"></div>
What is the best way to do it?
(I'm using ui-router.)
It looks like you need ngRoute or UIRouter.
These will allow you to define view behavior for a given URL in your app.
For example, if you wanted to define routes (using ngRoute) for '/login' and '/dashboard', it might look like this:
angular.module('ngRouteExample', ['ngRoute'])
.controller('MainController', function($scope) {
// Do stuff...
})
.controller('DashboardController', function($scope, $routeParams) {
// Do Stuff...
})
.controller('LoginController', function($scope, $routeParams) {
// Do Stuff...
})
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardController',
})
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
});
And in your index.html:
<div ng-view></div>
Then, you can create a separate directive like:
<sidebar></sidebar>
And include it in dashboard.html but not in login.html
EDIT
If your layout will allow, you could include the sidebar a single time in index.html and render or not render it with ng-if based on a scope variable that you set by checking $routeParams.
In that case, your 'mainController' would look like this:
.controller('MainController', function($scope, $route, $routeParams, $location) {
$scope.showSidebar = function(){
if($routeParams.paramName == 'login'){
return false;
}else{
return true;
}
};
})
Then in index.html
<sidebar ng-if="showSidebar()"></sidebar>
So I guess you want to avoid having to include the sidebar in every view you make?
Maybe something like this?
In your route file, you can create an extra parameter like this:
$stateProvider
.state('login', {
url: '/login',
templateUrl: '/App/tpl/login.html',
hideSideBar: true
})
Which you can then access in your controller/directive like this:
$state.current.hideSideBar;
That way you can include the sidebar in your main layout and hide it when set to true like this:
<div id="sidebar" data-ng-hide="controller.hideSideBar">
.... your sidebar
</div>
(this is all written from memory so it may not work straight out of the box, but it should get you started)

AngularJS relative url routing issue

I have my backend web framework loading my AngularJS app with following URL
http://localhost/New/Alpha/App
I also have it set up so that anything after App will still load the same thing
http://localhost/New/Alpha/App/home
http://localhost/New/Alpha/App/settings
...
I'm trying to make my AngularJS app to work in the way that it would pick up the bit of URL after App and load a controller/template accordingly. I have a problem with routing in my AngularJS app though
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
If I try this URL
http://localhost/New/Alpha/App/home
it changes the URL to
http://localhost/fail
instead of leaving the URL as it is and loading the template/controller. If however I change the config and give it a full relative URL it does work as supposed to
.when("/New/Alpha/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
My problem is, that the part of URL before App - /New/Alpha cannot be hardcoded in. It could be /New/Beta, /New/Gamma, etc.
Is what I want to do possible at all without hardcoding the full relative URL match?
UPDATE Sorry, forgot to mention that the number of URL segments before App can change, as in it could be /New/Beta/App and it also could be /New/Another/Beta/App. I don't suppose something like */App or /New/*/App is possible instead of /New/:placeholder/App?
Will this work for you?
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/New/:greek/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
You could then retrieve the greek with $routeParams.greek from within your controller.
The general solution to this problem is to have the server pass the app URL to your client-side code. In other words, use server-side code to dynamically write the equivalent of the following on the page:
var appUrl = '/New/Alpha/App';
Then setting up the route provider becomes:
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when(appUrl + "/home", {
templateUrl: "/assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: appUrl + "/fail"
});
$locationProvider.html5Mode(true);
});
That way the knowledge of the application base URL lives in one place — server-side (which makes sense as only the server is in a position to truly know, if you think about it).
In your specific case, if the application base URL is implicit in the URL structure, you could calculate the following client-side:
var appUrl = window.location.pathname.match(/^\/New\/.*\/App/);
Needs work, but you get the idea. Then you can set up the route provider exactly as above.

Localizing routes in Angular

I am trying to create an Angular app in multiple languages but I have come across and issue with the routing. I found a workaround to make the necessary routes valid for 2 languages :
var app = angular.module("app", ["localization", "ngResource", "ngRoute"]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/en-US/Gameplan/Admin/Fixtures/List', { controller: FixtureListController, templateUrl: '/Content/Templates/Fixtures.html' }).
when('/da-DK/Gameplan/Admin/Fixtures/List', { controller: FixtureListController, templateUrl: '/Content/Templates/Fixtures.html' }).
when('/en-US/Gameplan/Admin/Fixtures/Add', { controller: FixtureAddController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
when('/da-DK/Gameplan/Admin/Fixtures/Add', { controller: FixtureAddController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
when('/en-US/Gameplan/Admin/Fixtures/Edit/:fixtureId', { controller: FixtureEditController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
when('/da-DK/Gameplan/Admin/Fixtures/Edit/:fixtureId', { controller: FixtureEditController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
otherwise({ redirectTo: '/en-US/Gameplan/Admin/Fixtures/List' });
$locationProvider.html5Mode(true); //will use html5 mode rather than hashbang where available
});
However, I still have an issue with links, currently my links look like this :
<i class="glyphicon glyphicon-plus"></i>
<i class="glyphicon glyphicon-edit"></i>
I don't want to hard code the URL and I have a client side object that returns the locale (in this case either en-US or da-DK), but I have been unable to dynamically set the href values. Is there any way to do this in Angular, or a different approach altogether regarding localizing routes?
This isn't AngularJS specific, but why not set a cookie as soon as you know what language the user wants for the UI? Then both the client and server have ready access to it on every page and you don't have to shuttle it around in the URL.
This might be too late, but in case you are using Angular 2x there is a library localize-router. You can find it here.

Categories

Resources