Build URLs based on routes - angularjs

Is there a way to build an URL based on the defined Angular routes? Something like Symfony does (http://symfony.com/doc/current/book/routing.html#generating-urls).
Here is an example of how it would be used:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/document/:documentId', {
name: 'document',
templateUrl: 'partials/document.html',
controller: 'documentController'
});
}]);
Then in templates we could use something like:
View document
That would be compiled into:
View document

I have user $stateParams (from angular-ui-router) for this.
.controller('MainCtrl', function ($scope, $stateParams) {
$scope.link = $stateParams.documentId;
});
UI Router wiki on Github

Related

How do I activate otherwise on ui.router for Angular 1?

I have a situation where a third party library adds "#checkout" at the end of the URL (it's Snipcart) but Angular cannot seem to detect it and it just goes back to the /test page (localhost:3000/test).
The reason the URL is: /test is intentional as I have html5mode enabled.
This works well in a normal static HTML project (so not Angular) but when I used ui.router with Angular 1.x, it doesn't work.
My angularApp.js file:
var mainApp = angular.module('mainApp', ['ui.router']);
mainApp.config(function($locationProvider, $stateProvider, $urlRouterProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise(function(){
console.log('otherwise activated');
});
var helloState = {
name: 'root',
url: '/',
templateUrl: '/partial/main.html',
controller: 'mainController'
}
var aboutState = {
name: 'test',
url: '/test',
views: {
'#': {
templateUrl: '/partial/yamuna.html',
controller: 'testController'
}
}
}
$stateProvider.state(helloState);
$stateProvider.state(aboutState);
});
mainApp.controller('mainController', ['$scope', '$rootScope', function($scope, $rootScope){
console.log('mainController activated');
}]);
mainApp.controller('testController', ['$scope', '$rootScope', function($scope, $rootScope){
console.log('testController activated');
}]);
So the paths below work as expected:
localhost:3000/ ##mainController activated
localhost:3000/test ##testController activated
But, Snipcart appends the path to:
localhost:3000/test#checkout - which I want to be able to go to the otherwise route and not fall back to localhost:3000/test#
Any way around this? As Angular 1 is quite old, I will have to come up with a workaround myself.
Edit
I can detect the path change with: (FYI this one below is in ngRoute as I was playing around with the various options):
mainApp.run(
['$rootScope', '$location', '$window', function($rootScope, $location, $window) {
$rootScope.$on("$routeChangeStart",
(event, current, previous, rejection) => {
console.log($window.location.href);
})
}])
But - what do I do after that? I can filter out only that specific path where #/checkout is hit but where do I redirect the site to? Not sure if this is even worth an edit but I thought I will mention it for completeness.
My ONLY option it seems is to upgrade to Angular 8 or higher but as I am so close to the deadline, I will like to explore all the options with Angular 1.x first.
Thanks

AngularJS 1.6.7 controller breakdown and refactor into components

i'm having angularJS app where all controllers are in one file , i want break it down and seperate each controler then refactor it to component based as it's recommended for angularJS 1.5 and above. my current structure looks like this:
.controller('HomeController', ['$scope', function ($scope){
//logic
}
])
and the same for all other controllers are in the same file "controllers.js", in my app.js i do:
var app = angular.module('app', [
'services',
'controllers',
]);
what you advice to break down the controllers into components, thank you for answers and recommendations.
Provided that you are using $scope, you could start by changing from scope to controllerAs syntax, that is, $scope.foo = 'bar' -> <p>{{ foo }}</p> would become this.foo = 'bar' -> <p>{{ ctrl.foo }}</p>.
controllerAs Syntax
From this:
app.controller('HomeController', ['$scope', function ($scope){
$scope.title = 'Home';
}]);
To this:
app.controller('HomeController', [function (){
this.title = 'Home';
}]);
declaring components
Afterward, you'd be able to declare your components in two ways:
Partial refactor using the existing controller:
app.component('homeComponent', {
controller: 'HomeController'
});
Or, full refactor replacing the controller:
app.component('homeComponent', {
controller: [ function (){
this.title = 'Home';
}]
});
refactoring routers
Assuming that you are using ui-router (it's very similar to ngRoute so it wouldn't be a problem).
From this:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home/home.html',
controller: 'HomeController'
})
To this, for ui-router 1.0+:
$stateProvider
.state('home', {
url: '/',
component: 'homeComponent'
})
Or this, for older versions:
$stateProvider
.state('home', {
url: '/',
template: '<home-component></home-component>'
})
Ref.: Guide: Route to Component
final thoughts
There's a pretty good style guide for angularjs written by John Papa that you should have a look at and use what's worth for you. However, as it's been told by #MikeFeltman it's not accurate with angularjs 1.5 components application style practices; therefore, you should have a look at Todd Motto's revised version of the guide including component application practices.
Disclaimer: I see no point in converting a controller to a directive before making the component, you can declare the component directly because components are special directives and they carry a controller so it's convenient for you.

Error when adding more than one app module

I am using two app modules in this app. Why do I get this error? I define the navCtrl in my index.html file where ng-view is like this:
<body ng-app="ciscoImaDashboardApp" ng-controller="navCtrl">
Error: [ng:areq] Argument 'navCtrl' is not a function, got undefined
What am I doing wrong? Am I getting this because I define angular.module in all my js files?
Routes JS:
angular.module('ciscoImaDashboardApp', ['ciscoImaDashboardAdmin', 'ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: 'views/admin.html'
})
.when('/', {
templateUrl: 'views/welcome.html',
controller: 'welcomeCtrl'
})
.when('/overall-results', {
templateUrl: 'views/overall.html',
controller: 'overallCtrl'
})
.when('/swim-lane-results', {
templateUrl: 'views/swim-lane.html',
controller: 'swimlaneCtrl'
})
.when('/key-exemplifiers', {
templateUrl: 'views/key-exemplifiers.html',
controller: 'petalCtrl'
})
});
Second Module:
angular.module('ciscoImaDashboardAdmin',[])
.controller('minisCtrl', function ($scope) {
});
Nav JS:
angular.module('ciscoImaDashboardApp',['ciscoImaDashboardAdmin'])
.controller('navCtrl', function($scope, navService, $location, dummyData) {
});
right way :
angular.module('ciscoImaDashboarAdmin')
.controller('minisCtrl', function ($scope) {
});
remove dependency practice in the second time
from angular js documentation you can find below block check the link here
Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.

how to implement Rooting angularJS with customize url

I want to have on the URL of my application like this:
http://localhost:9000/#/?id=XYZ
I don't found how to configure this on angularjs app module
My implementation is like that:
angular.module('APP', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when("/?id="+":id", {
templateUrl: "views/sign/sign.html",
controller: "SignCtrl"
});
// $locationProvider.html5Mode(true);
});
but It doesn't work.
You do not have to specify
it will be like
angular.module('APP', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when("/", {
templateUrl: "views/sign/sign.html",
controller: "SignCtrl"
});
// $locationProvider.html5Mode(true);
});
and in your SingCtrl.
when you write $routeParam than you will have objects of params which are passed as a query parameter.
so you will get $routePara.id if you pass like ?id=anything
Do not have to worry if you want to catch the query param like ?id=abs&name=test
You can add a "url" attribute to your $routeProvider object.
Something like:
$routeProvider.when("/?id="+":id", {
templateUrl: "views/sign/sign.html",
url: 'the Url you want to use',
controller: "SignCtrl"
});
PS.: I suggest you to use ui-router instead of ngRoute. Check it out later.

ngRoute not directing to anything

So I'm trying to learn how to use Angulars routing, following tutorials online, and I can't seem to figure out where I'm going wrong. I have the following code:
var app = angular.module('gamersplane', ['controllers', 'ngCookies', 'ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/pms/:box?', {
controller: 'pmList'
}).when('/pms', {
controller: 'pmList'
}).otherwise({
controller: 'pmList'
});
}])
var controllers = angular.module('controllers', []);
controllers.controller('pmList', function ($scope, $cookies, $http, $routeParams) {
console.log($routeParams);
});
However, no matter what I do, the controller doesn't get hit. I have otherwise in the router, so isn't that where it should hit if all else fails?
Yes it will hit otherwise but you can only define the redirect path into it and that redirect path will tell the url and the controller to set for the $route.current :-
redirectTo: '/pms'
Doc
You need to add a template to each route:
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/pms/:box?', {
controller: 'pmList',
template: 'test.html'
}).when('/pms', {
controller: 'pmList',
template: 'test.html'
}).otherwise({
controller: 'pmList',
template: 'test.html'
});
}])
squiroids suggestion regarding otherwise was correct, you won't see a change in your test application though.
Routing is meant to be used to navigate between regions of your application. You could have an app with two routes: pms which shows a list of PMs and pms/:box zu view a particular PM Box. The main task for ngRoute is to replace a placeholder in your application (ng-view) with a given template. Without using a template on the individual routes, your $routeProvider will not navigate as expected.
Given you have two views for the regions (pmBox.html and pmList.html), you could configure your $routeProvider zu setup routing like this: https://gist.github.com/kpko/bd0231ccefbaf8c415c7

Resources