Multiple routes sharing one controller, how about different titles? - javascript

I'm re-writing an app using angularjs.
Until today each route of the app had each own controller and a title as well for the prowser using a service like that:
myApp.factory('PageTitle', function(){
var title = 'Default title';
return {
title: function() { return title; },
setTitle: function(newTitle) { title = newTitle; }
};
});
which the i use in the controller like that:
PageTitle.setTitle(TitleVariable);
That worked perfectly until now.
I need as i said to re-write my app to have only one controller for all the routes.
So i'm trying to run a function looking at the route change with the current route path to update the title (which i forgot to mention is a dynamic information, so i cannot add a title variable in the routes file i guess) but it just not working.
What is the correct way to achieve that?
My routes looking that that:
myApp.config([
'$routeProvider',
'$locationProvider',
function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(false).hashPrefix('!');
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'views/homepage.html'
})
// route for the home page
.when('/home/:pageSlug/', {
templateUrl : 'views/homepage.html'
})
etc.
I'm calling the controller in the index.html file on header like:
<html data-ng-app="myApp" data-ng-controller="appCtrl">
And i'm getting the title like that:
<title data-ng-bind="PageTitle.title()"></title>

Related

resolve not running before entering route

this is a jsbin showing the problem, however, I will explain it here. I am trying to use resolve to run some code before entering a route, however, it doesn't run (as the console.log statement provides more detail about). (Since it doesn't run, I'm not sure if I'm setting what would be the return value from resolve in the template correctly). Why isn't resolve running?
var app = angular.module('jsbin', ['ngRoute'])
.config(function ($routeProvider) {
'use strict';
console.log("this runs");
var routeConfig = {
controller: 'DemoCtrll',
resolve: {
store: function (demoStorage) {
console.log("this doesn't log");
return demoStorage;
}
}
};
$routeProvider
.when('/', routeConfig)
.otherwise({
redirectTo: '/'
});
});
app.controller('DemoCtrl', function($scope, $routeParams, store) {
this.name = store;
});
app.factory('demoStorage', function () {
'use strict';
return "World";
});
html
<body ng-app="jsbin">
<div ng-controller="DemoCtrl as demo">
<h1>Hello {{name}}</h1>
</div>
Some changes you would need:
You cannot use ng-controller directive along with ng-view's route bound controller, i.e set controller alias in the controller property of the route config controller: 'DemoCtrl as demo',.
When you use ng-controller directive to instantiate the controller it does not know what is store provider, because no such provider/service exists. It is a special dependency injected by the angular router and only the router knows how to inject store as dependency in your controller. That is the reason for the error when you used ng-controller.
You need to define a template html or a template and bind it to templateUrl property on the routeConfig. i.e templateUrl:'demo.html',
Remove ng-controller from the view.
You need to use ng-view directive to render the view. i.e in your index.html <ng-view></ng-view>
Since you are using controller alias you would refer to the property as demo.name in the view rendered by the route.
You also had a typo in the controller name #DemoCtrl1.
Overall it will look like this.
Define your template in say Demo.html (In the demo example i have used the convenient script type="text/ng-template")
<div>
<h1>Hello {{demo.name}}</h1>
</div>
Set the routeConfig:
var routeConfig = {
templateUrl:'demo.html',
controller: 'DemoCtrl as demo',
resolve: {
store: function (demoStorage) {
console.log("this doesn't log");
return demoStorage;
}
}
};
JSBin
Also see this answer though it uses angular ui-router, but the concept is the same.

AngularJS Routing Not Working As Expected

I'm new to AngularJS and very lost at this point. I am trying to learn from this code:
http://plnkr.co/edit/dd8Nk9PDFotCQu4yrnDg?p=preview
script.js:
// create the module and name it scotchApp
var scotchApp = angular.module('scotchApp', ['ngRoute']);
// configure our routes
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function($scope) {
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
scotchApp.controller('aboutController', function($scope) {
$scope.message = 'Look! I am an about page.';
});
scotchApp.controller('contactController', function($scope) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
My index.html file includes
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
I have it set up on a local environment. I can load the main page but the routing only changes the URL, nothing else. Any ideas what could be causing this?
When you say only Url is called and page is not rendered means, ngroute works fine. One thing you need to make sure is that all html files reside under pages directory.
Also there should be <ng-view> tag inside index.html page
The best example is the plunker you are referring to.
I found the solution to my problem. I had to add
app.use(express.static(__dirname ));
To my node server script. I don't understand why this was needed, though.

How can I get page to reload when I Use Angular UI router

I am new to angular and am trying to build a small application, I am using .Net for my web api and have coded a HttpResponseMessage Post method that returns a JWT. Before I start to use the JWT I just want to hit the back end, get the JWT and if it comes back redirect to another view. I am using UI Router to do this
My code looks something like this:
controller
(function () {
function LogInController($scope, $http, $state) {
$scope.signOn = function () {
$http.post('http://localhost:route to my backend').then(function (response) {
if (response.data.token) {
$state.go("main");
} else {
alert('you do not have a token');
}
});
};
};
app.controller("LogInController", LogInController);
}());
Html:
Sign in
app.js
"use strict";
//defines the main module
var app = angular.module("app", ["ui.router"]);
app.config(function ($stateProvider) {
$stateProvider
.state("main", {
url: "/main",
templateUrl: "MedOrders.html",
controller: "MedOrdersCtrl",
});
});
this currently works, it hits my back end and shows me my token. I tried to change it to the following and got a ton of injector errors
app.js using UI router
var app = angular.module("app", ["$state"]);
app.config(function($state) {
$stateProvider
.state("main", {
url: "/main",
templateUrl: "where/my/view/lives.html",
controller: "newViewsController"
});
});
I am trying to start off simple which is why I do not have a login service and that may be my problem, but I am not quite sure, when I try to run this UI router fails silently. I end up still on the log on page but with the #/main appended. Should I be doing something to force this redirect the angualr way? And is there a way to get error messages from UI router?
You are using the ngRoute module as dependency while you are using ui.router in the rest of the code.
Changing the dependency to ui.router will solve the errors at least
var app = angular.module("app", ["ui.router"]);

$routeProvider.when(..) not catching all URLs

setup: jade, angular, express, node.
In my routeProvider of angular, I am having some issues. I am requesting a url with a parameter which it is not catching.
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
//... omitted some url/pages here
//start of SPA
.when('/dashboard/', {
templateUrl: 'partials/index',
controller: 'dashIndexCtrl'
})
.when('/dashboard/class/:id',{
templateUrl: 'partials/class',
controller: 'classCtrl'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}]);
When I call localhost/dashboard/class/TEST
I get redirected to root.
I declare my routes on the server side as follows:
app.get('/dashboard', routes.dashboard);
app.get('/dashboard/partials/:name', routes.partials);
app.get('/api/class/:id', api.classGet);
My controller name matches up with the routeProvider. In which case the controller code goes as follows:
app.controller('classCtrl', function($scope, $http, $routeParams){
$http.get('/api/class/' + $routeParams.id)
.success(function(dataJson){
console.log(dataJson);
});
});
Why is routeProvider missing this url? I have set breakpoints within my controller so I am certain it is not being called. Also my partials/class.jade is not being called. Let me know if you need anymore code or directory information. Thanks in advance.
After further investigation:
If I go: localhost/dashboard/partials/class it will load that jade file. So it is definitely the controller.
Directory structure, I believe this is my issue now....
+---\
| +---\views
| +---index.jade
| +---dashboard.jade
| +---\partials
| +---index.jade
| +---class.jade
Take a look into console and observe that AngularJS tries to load templates from /partials/index then from /dashboard/partials/index
Solution
set templateUrl path as /dashboard/partials/index in config section.
Reason: angular-route.js
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
if (angular.isDefined(templateUrl)) {
next.loadedTemplateUrl = templateUrl;
template = $http.get(templateUrl, {cache: $templateCache}).
then(function(response) { return response.data; });
}
There is no concatenation templateUrl with route path – just load tempalteUrl from Angular root of application.

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.

Categories

Resources