angularJs navigation's from ng-route to ui-router - angularjs

I am new to AngularJS, and I am a little confused of how I can use angularjs ui-router in the following scenario:
It consists of two sections. The first section is the Homepage with its login and sign up views, and the second section is the Dashboard (after a successful login).
When I logged in success need to navigate from login form to "Home page".
When I tapped a registration button I need to navigate to "Registration page" from login page
Similarly I also need a "forgot password" screen
My current router is below. How can I do this functionality? (Please help with some HTML code and related controllers)
app.js:
'use strict';
//Define Routing for app
angular.module('myApp', []).config(['$routeProvider', '$locationProvider',
function($routeProvider,$locationProvider) {
$routeProvider
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller: 'RegisterController'
})
.when('/forgotPassword', {
templateUrl: 'forgotpassword.html',
controller: 'forgotController'
})
.when('/home', {
templateUrl: 'views/dashBoard.html',
controller: 'dashBordController'
})
.otherwise({
redirectTo: '/login'
});
}]);
});

Firstly, nobody will design a website with your requirements / functionalities for you. stackoverflow is for specific problems, your questions is too broad, more about it - How to Ask. But to help you with a conversion from ngRoute to ui.router I can describe what the syntax should look like so you can adopt it for your website.
Converting to ui.router
Your config doesn't change that much. you need to replace .when with .state, use the right providers, and have the right syntax. Here is an example with just few states:
app.config(config);
/* your preferred way of injecting */
config.$inject = ['$stateProvider', '$urlRouterProvider'];
function config($stateProvider, $urlRouterProvider) {
$stateProvider.
state("HomepageState", {
url: "/home",
templateUrl: 'views/dashBoard.html',
controller: 'dashBordController'
}).
state("RegisterState", {
url: "/register",
templateUrl: 'register.html',
controller: 'RegisterController'
})
/*
more can be added here...
*/
$urlRouterProvider.otherwise('/login');
}
Navigation
You should be using states for navigation at all times. So replace href="url" with ui-sref="state". Here are some examples of anchor links:
<a ui-sref="HomepageState">Home page</a>
<a ui-sref="RegisterState">Register</a>
Don't forget to replace your ng-view with ui-view. (For older browser support it's better to have <div ui-view></div> instead of <ui-view></ui-view>)
Redirection
After filling in a login form, the user will press something like:
<button ng-click="login()">Sign in</button>
which will call a function login() that will validate / verify if the user can be logged in. (You can also have <form ng-submit="login()"> with <button type="submit">...) Then, if everything is fine and the user got his session / cookie, you can have a redirection to another page with:
$state.go("HomepageState");
(Don't forget to inject $state into your controller)
Advanced navigations
In the future if you have user profiles that are listed by their index. Your routing can be improved with $stateParams. Their job is to check any additional parameters in the URL. For example: a URL: /profile/721 can have a state with url:"/profile/:id". Then you can extract that id with $stateParams.id and use it in your controllers. And your redirection would look like:
$state.go("ProfileState", { "id": 721});

Related

Angular ui-router customization issue

I am in trouble with a specific requirement here for our Application.
We a are setting-up an angular application inside a pre-existent Rails Application.
As a full refactor of our code-base is currently out-of-the-question we are dealing with some hard customization and hackings on both sides to allow a incremental introduction of Angular.
What we need for now is a way to tell the ui-router to bind only to the links we have the ng-sref attribute and do not bother with all the regular href links within our app.
Is there a way to achieve this behavior ?
Below is my current code:
angular.module('app').config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider.state('test', {
url: "/1/test",
template: 'test'
});
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
})
}
)
With this approach, all links, even those ones without any route setup for it, and without a ui-sref attribute, are being watched by angular routing service and prevented to work like it`s previous behaviour. I do not want to add every route of our huge app to the angular routing setup (this is a terrible idea) because most of theses links are to non-angular pages. I just want angular routing service to ignore this links, or these locations that are not defined. Maybe a setting for the $location service to let those guys fallow along with its previous behaviour (ajax requests, regular requests, or Turbolinks requests). I am pretty sure this is something really trivial that I might be missing the point.
What happens when I click on theses links is that the window location changes, but nothing happen. The browser request is not triggered.
Thank you very much in advance.
###################################################################################
# My suggestion is use the ui-router to route to specific pages as shown
# in the example below.
# <a ui-sref="/login">
# <a ui-sref="/logout">
# <a ui-sref="/signup">
# <a ui-sref="/profile">
# 'ui-sref' will take you to the specific pages.
# You can also use '$state.go' to take you to specific pages as shown below.
# $state.go('authentication.login');
# $state.go('authentication.logout');
# $state.go('authentication.signup');
# $state.go('authentication.profile');
###################################################################################
(function() {
'use strict';
angular
.module('app.foo.authentication')
.config(moduleConfig);
/* #ngInject */
function moduleConfig($translatePartialLoaderProvider, $stateProvider) {
$translatePartialLoaderProvider.addPart('app/foo/authentication');
$stateProvider
.state('authentication.login', {
url: '/login',
templateUrl: 'app/foo/authentication/login/login.tmpl.html',
controller: 'LoginController',
controllerAs: 'vm'
})
.state('authentication.logout', {
url: '/logout',
templateUrl: 'app/foo/authentication/logout/logout.tmpl.html',
controller: 'LogoutController',
controllerAs: 'vm'
})
.state('authentication.signup', {
url: '/signup',
templateUrl: 'app/foo/authentication/signup/signup.tmpl.html',
controller: 'SignupController',
controllerAs: 'vm'
})
.state('authentication.profile', {
url: '/profile',
templateUrl: 'app/foo/authentication/profile/profile.tmpl.html',
controller: 'ProfileController',
controllerAs: 'vm'
});
}
})();

AngularJS: routeChangeError different from $routeProvider.otherwise?

Currently I have $routeProvider.otherwise configured to go to a page behind the login, and if that page does not resolve, they go to the login screen. I would like an additional redirection to an error page when an XHR fails that is meant to redirect the user to a success page. I have found that if I register a listener on routeChangeError to redirect to /error instead of the defaults, the .otherwise is overridden and all mistyped links take the user to the error page. Does angular provide anything that allows for this? Or maybe I missed something in my code? I can write it if angular doesn't provide it, but I'm just wondering if there is a feature native to the framework.
$rootScope.$on("$routeChangeError", function () {
$location.path("/login")
})
app.config(['$routeProvider', function ($routeProvider, $route) {
$routeProvider.
when('/error', {
templateUrl: 'error.html',
controller: 'Error',
controllerAs: 'error'
}).
when('/status-info', {
templateUrl: 'status-page.html',
controller: 'StatusInfoController',
resolve: {
auth: function (SessionService) {
return SessionService.resolve()
}
}
}).
when('/', {
redirectTo: '/status-info'
}).
otherwise({
redirectTo: '/'
})
Additional info
The desired outcome is a website that responds to incorrect URLs in the usual way - defaulting to a specific page behind login or login if not authenticated, but with the extra twist of having a special error page for rejected $route.resolve() promises.
I would love to write a plunkr for you, but I can't get to it tonight. We're launching the beta this weekend! I don't necessarily need code if you can just set me in the right direction. Any help you can offer would be great.

How to combine ng-view with complete pages in AngularJS?

I am developing an application that is supposed to be a single-page application.
The tools I am using are AngularJS, NodeJS, ExpressJS and Jade for templating.
So far I've been working with a page that has a ng-view directive on it, and I can change its content to display the page I want, while maintaining the side menu.
Now I've come to a point where I need to create a login/create account page (that I am calling 'intro', for now), and this one should use all the screen space, removing the menu as well.
How can I achieve this? My route file looks as follows:
var akaAcademicManagerApp = angular.module('akaAcademicManagerApp', ['ngRoute', 'akaAcademicControllers']);
akaAcademicManagerApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/dashboard', {
templateUrl: 'partials/dashboard',
controller: 'DashboardController'
}).
when('/profile', {
templateUrl: 'partials/profile',
controller: 'ProfileController'
}).
when('/intro', {
templateUrl: 'partials/introPage',
controller: 'IntroController'
}).
otherwise({
redirectTo: '/dashboard'
});
}]);
angular.module('akaAcademicControllers', []);
I think this can help you (yet, i don't think it's the optimal solution but it works)
in your index.html,after your body tag put this:
<div ng-include="accessToApplication()"></div>
Now in your controller:
$scope.loggedIn = false;// true when the user is logged in
$scope.accessToApplication = function () {
if (!$scope.loggedIn) {
return "partials/introPage.html";
}
else {
return "path to the page containing the ng-view";
}
};
I advice you to take a look at ui-router and multiple named views (https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views)

Excluding path in url using AngularJS

My angular application has multiple pages which users can visit and I would like to hide all other urls and only show users the base url. So imagine my base url is: www.example.com and I have other pages like About, Contact Us etc. Currently, when the user clicks on About, the url changes to www.example.com/about. Is it possible for angular not to add the "/about"? Is this possible using angular js? Also, I have been searching for solutions and have experimented with ui-router.js, is it also possible with this module?
If you are using ui-router, then you can define states without specifying urls like
myApp.config(function($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/state1");
//
// Now set up the states
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "state1.html",
controller: 'Controller3'
})
.state('state2', {
templateUrl: "state2.html",
controller: 'Controller2'
})
.state('state3', {
templateUrl: "state3.html",
controller: 'Controller3'
})
});
So by default the url will be /state1. And you can implement navigation by using ui-sref directive in your template like ui-sref="state2" or using $state service in your controller like $state.go('state2').

Using binding with UI Router

I am working with ui-router and have several states defined. On one of my views I have a form where a user can add a 'team' to the view. I have a button for each team to view additional details on that team. What I am trying to do is set it up so that when I click on that button the team view comes up with the URL like /#/teams/yankees for example.
I may just not be looking in the right places or know the exact term for this, but I have not been able to figure it out so far.
Below is a snippet of what I currently have in my app.js for this portion.
app.config(
['$stateProvider','$urlRouterProvider',
function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/');
.state('teams', {
url: '/teams',
templateUrl: './templates/main/teams.html',
controller: 'teamsCtrl'
})
.state('teams/{{ team.title }}', {
url: '/teams/{{ team.title }}',
templateUrl: './templates/main/team.html',
controller: 'topicCtrl'
})
Whenever I click on the button now to go to /#/teams/yankees I end up being routed by $urlRouterProvider.otherwise('/'); Can someone point me in the right direction?
It would be helpful to know what your links look like... are you using ui-sref? Typically url attributes look more like this like this:
.state('teams/{{ team.title }}', {
url: '/teams/:title',
templateUrl: './templates/main/team.html',
controller: 'topicCtrl'
})
rather than the {{}}

Resources