What href to set for routeProvider in Angular JS? - angularjs

I have page with ng-view. This page is generated by php following URL: www.sbt.com/profile
What url I need to set in href attribute, that will work Angular JS by url:
www.sbt.com/profile/privacy/1
I tried:
.when('/profile/:page/:type', {}
And link like as:
Go
But it does reload page at url when I click to link in page /profle:
www.sbt.com/#/profile/personal/1
Full code is:
.config(function ($locationProvider, $routeProvider) {
$routeProvider
.when('/profile/:page/:account', {
templateUrl: function(params) {
return '/public/html/personal.html';
},
controller: 'EditProfileController'
})
/* Chat */
.when('/chat/dialog/:id', {
controller: 'ChatController'
});
})

If your angular application is served from the page with base URL like /profile then links should look like:
Go
and route configuration should be
.when('/:page/:account', {
templateUrl: function(params) {
return '/public/html/personal.html';
},
controller: 'EditProfileController'
});
Also make sure you define base href (although it should work without it too in your case). Put this script in the <head> of the page:
<script>
document.write('<base href="' + document.location + '" />');
</script>

Related

fails to load assets file on page reloading angularJS

I have the following routes:
/**
* General app route
*/
angular
.module('app')
.config(config);
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/index.html',
controller: 'ImageController'
})
.when('/category/:name', {
templateUrl: 'partials/index.html',
controller: 'CategoryController',
})
.when('/404', {
templateUrl: 'partials/404.html'
})
.otherwise({ redirectTo: '/404' });
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
when I'm trying to access the category route from base route it works fine, but when I reload the page on category route it tries to access the assets file through category path instead of base path.
how can I fix it?
I figured it out by adding base tag to index.html
<head>
<base href="/index.html">
</head>
One way is the disable HTML5 mode
$locationProvider.html5Mode({
// enabled: true,
requireBase: false
});
Other way is to make sure the server side routing returns correct HTML file.
You have activate html5 mode, and for that you need redirect all the traffic to the index.html
See the section html5 mode for more details https://docs.angularjs.org/guide/$location

Sub Domain Routing in AngularJS

Hello i am new to AngularJS, i have done my research and i know redirecting to a sub domain will cause the page to refresh. What i want to know is how to check what the sub domain is when a link is clicked and load the right view and controller.
I use wildcard sub domains but i basically have three of them right now:
administrator.example.com
manager.example.com
employee.example.com
Each sub-domain should redirect you to their respective dashboard view and controllers.
The main url however example.com shall direct you to the website itself.
I have set-up my states like this:
app
app.administrator
app.administrator.dashboard
app.manager
app.manager.dashboard
app.employee
app.employee.dashboard
Here i am going to give you standard solution to your problem. You should create a separate application for each subdomain. I have created a sample application to demonstrate the flow.
Index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="jquery#2.0.0" data-semver="2.0.0" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link data-require="bootstrap#3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script data-require="bootstrap#3.3.5" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="app.manager.js"></script>
</head>
<body>
<load-application></load-application>
</body>
</html>
app.js
/**
* #name app
*
* Lets create angular application module
* if second parameter is passed with enpty array [] or with dependecies , is * called angular module setter
*
* angular.module('app', []); Setter
* angular.module('app'); Getter
*/
angular
.module('app', ['appLoader']);
/**
* app.administrator application for aministrator subdomain
*/
angular
.module('app.administrator', ['ui.router']);
/**
* app.employee application for employee subdomain
*/
angular
.module('app.employee', ['ui.router']);
/**
* Lets create a application loader
* This component is going to load sub domain specific application
*/
angular
.module('appLoader', ['app.administrator', 'app.manager', 'app.employee'])
.directive("loadApplication", ['$location', function($location) {
function getDomain() {
console.log($location.host());
//get domain name here
return 'manager';
}
return {
restrict: 'E',
controller: function($scope, $element, $attrs, $transclude) {},
template: function() {
var domainName = getDomain(),
templateName = '';
switch (domainName) {
case 'manager':
templateName = '<app-manager></app-manager>';
break;
case 'employee':
templateName = '<app-employee></app-employee>';
break;
case 'administrator':
templateName = '<app-administrator></app-administrator>';
break;
}
return templateName;
},
link: function($scope, element, attrs) {
console.info('loader application');
}
};
}]);
angular
.module('app.administrator')
.directive("appAdministrator", ['$location', function($location) {
return {
restrict: 'E',
template: '<h2>{{applicationName}}</h2>',
link: function($scope, element, attrs) {
$scope.applicationName = 'Application Administrator';
}
};
}]);
angular
.module('app.employee')
.directive("appEmployee", ['$location', function($location) {
return {
restrict: 'E',
template: '<h2>{{applicationName}}</h2>',
link: function($scope, element, attrs) {
$scope.applicationName = 'Application Employee';
}
};
}]);
app.manager.js
angular
.module('app.manager', ['ui.router']);
angular
.module('app.manager')
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index', {
url: '/',
template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li><li><a ng-href="#" ui-sref="demopage2">Demo page 2</a></li></ul>'
})
.state('demopage1', {
url: '/demopage1',
template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li></ul>'
})
.state('demopage2', {
url: '/demopage2',
template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li></ul>'
})
});
angular
.module('app.manager')
.directive("appManager", ['$location', function($location) {
return {
restrict: 'E',
template: '<h2>{{applicationName}}</h2><div ui-view></div>',
link: function($scope, element, attrs) {
$scope.applicationName = 'Application Manager';
}
};
}]);
Working plunker is here
I have created 3 applications for three domains , each application works independently. I have implemented the UI routes in app.manager application. You can implement the same in rest applications.
Lets me know if you have any concern ?
If you haven't started using the routing module called ui.router in your angular-based app, I suggest you read it here. I believe it is much more powerful than the ngRoute module native in Angular 1.x.
From my understanding your subdomain, I think you can arrange them as nested domains (or to be more precise, states) under 'app'. If the root url of your 'app' is something like '/main/', then the subdomains will inherit that root url and take the form such as '/main/administrator' and '/main/administrator/dashboard'
Each state (including nested states) can have its own controller, in which you can use the $state service in ui.router to get the state name (or subdomain name as you said) by calling: $state.$current.name
I hope this helps
As an example from my previous work. Here the main app has the url '/webapp', and the rest of the states are nested states that have their url started with '/webapp', e.g. for the state 'home.blogs', its url is '/webapp/blogs'. If it's still confusing, I suggest you spend some time reading the documentation on ui.router at Github.
angular
.module('blogFrontendApp', [
'ui.router'
])
config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/webapp/blogs');
$stateProvider.state('home', {
// abstract: true,
url: '/webapp',
views: {
'' : {
templateUrl: 'views/main.html'
},
'rightPanel#home' : {
templateUrl: 'views/rightPanel.html'
},
'mainContent#home' : {
templateUrl: 'views/mainContent.html'
}
}
})
.state('home.blogs', {
//to be shown in mainContent#home
url: '/blogs',
templateUrl: 'views/home_blogs.html'
})
.state('home.singleBlog', {
url: '/blog/:blogId/:blogTitle',
templateUrl: 'views/single_blog.html',
controller: 'blogArticleController as currentBlogView',
resolve: {
BlogService : 'BlogService',
blogObj : function(BlogService, $stateParams) {
return BlogService.getBlogById($stateParams.blogId);
}
}
})
.state('home.blogListInCategory', {
url: '/blogs/category/:categoryId',
templateUrl: 'views/blog_list_in_category.html',
controller: 'blogListController as blogListView'
})
.state('home.publishBlog', {
url: '/blogs/:categoryId/new',
templateUrl: 'views/publish_blog.html',
controller: 'blogListController as writeBlogView'
})
}

Ionic doesn't go into states with routing

There is the following index.slim:
doctype html
html ng-app="app"
head lang="en"
title First phonegap application
link href="bower_components/ionic/release/css/ionic.min.css" rel="stylesheet"
body
ion-header-bar
h1.title
| Header
ion-content
ion-nav-view
ion-footer-bar
h1.title
| Footer
script id="home.html" type="text/ng-template"
| 12345
script src="bower_components/ionic/release/js/ionic.bundle.min.js"
script src="js/main.js"
script src="cordova.js"
And the following main.js:
angular.module("app", ["ionic"]).config([
"$stateProvider", function($stateProvider) {
return $stateProvider.state("home", {
url: "/",
templateUrl: "home.html",
controller: "HomeController"
});
}
]).controller("HomeController", [
"$scope", "$state", function($scope, $state) {
return console.log(111);
}
]);
When I execute localhost:8888 (I use gulp server) I can see header/footer, but I don't see my home template and console output from controller. How can I fix it? Thanks in advance!

href with routeProvider loads a new page instead of binding the view

I'm stuck with routeProvider. my links keep opening a new page instead of loading the template in the view.
My code is the following
raceApp.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'raceApp/createChallenge_view.php',
controller: 'createChallenge'
})
.when('/createchallenge', {
templateUrl: 'raceApp/createChallenge_view.php',
controller: 'createChallenge'
})
.when('/findchallenge', {
templateUrl: 'raceApp/findChallenge_view.php',
//controller: 'findChallenge'
})
.otherwise({
redirectTo: '/'
});
}]);
My HTML looks like
<base href="/runkinlocal/wp-content/themes/wordpress-bootstrap-master/" />
<a class="menu-item select-runner0" href="#/createChallenge">
<a class="menu-item select-runner0" href="#/findchallenge">
When the page loads, the initial template is loaded, but then when I click on one of the links, a new page loads instead of loading the template in the view
( the page looks like http://test.com:8888/runkinlocal/wp-content/themes/wordpress-bootstrap-master/#/createChallenge)
I am working with Wordpress.
I'm looking forward to your help!
Working Example
plnkr
Suggestions
1. Your hrefs should not have #/
Create |
Find
2. Otherwise doesn't need redirectTo
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html'
})
.when('/createChallenge', {
templateUrl: 'create.php',
controller: 'CreateChallengeController'
})
.when('/findChallenge', {
templateUrl: 'find.php',
controller: 'FindChallengeController'
})
.otherwise("/");
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
});
3. Extra comma after last .when()
You have:
.when('/findchallenge', {
templateUrl: 'raceApp/findChallenge_view.php',
//controller: 'findChallenge'
})
The controller is commented out but there is still a comma.
4. You might need to configure html5
(see script.js in the plnkr)
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
5. You can add the base href like so
<script type="text/javascript">
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
</script>
Relevant Resources
I suggest checking these out:
$routeProvider docs
$route example
Let me know if that works!

Moving from individual templates to inline

I am using templateUrl to display specific php pages in my webpage. Now I wish to scrap the individual php pages and display code with variables passed to it. What is the easiest way to get back to this?
var AppModule = angular.module('App', ['ngAnimate', 'ngRoute']);
AppModule.config(function($routeProvider) {
$routeProvider
.when('/page:pageNumber', {
templateUrl: function ($routeParams) {
return '/app/..../assets/html/page' + $routeParams.pageNumber + '.php';
},
controller: "PageCtrl"
})
.otherwise({
redirectTo: "/page1"
});
});
AppModule.controller("ViewCtrl", function($scope, $timeout) {
$scope.$on("$routeChangeSuccess", function(event, current, previous) {
...stuff...
});
});
Use scripts via text/ng-template, which allows you to write your templates inline while declaring a url to access them by. The following code can go directly in your index.html, and if your config is set to show '/my-template.html', the inline template will be output right in the ng-view above it.
<ng-view />
<script type="text/ng-template" id="/my-template.html">
template goes here
</script>
Then in your config:
.when('/', {
templateUrl: '/my-template.html'
});
Here's a little more info from the Angular docs:
https://docs.angularjs.org/api/ng/directive/script
And lastly, this technique is demonstrated in one of the TodoMVC examples for Angular:
View: https://github.com/tastejs/todomvc/blob/gh-pages/examples/angularjs/index.html
Config: https://github.com/tastejs/todomvc/blob/gh-pages/examples/angularjs/js/app.js

Resources