Angular 1 - get current URL parameters - javascript

I want to extract data from current URL and use it in controller.
For example I have this url:
app.dev/backend/surveys/2
Bits that I want to extract:
app.dev/backend/ :type / :id
Is there anything in Angular that could help me with this task ?

To get parameters from URL with ngRoute . It means that you will need to include angular-route.js in your application as a dependency. More information how to do this on official ngRoute documentation.
The solution for the question:
// You need to add 'ngRoute' as a dependency in your app
angular.module('ngApp', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
// configure the routing rules here
$routeProvider.when('/backend/:type/:id', {
controller: 'PagesCtrl'
});
// enable HTML5mode to disable hashbang urls
$locationProvider.html5Mode(true);
})
.controller('PagesCtrl', function ($routeParams) {
console.log($routeParams.id, $routeParams.type);
});
If you don't enable the $locationProvider.html5Mode(true);. Urls will use hashbang(/#/).
More information about routing can be found on official angular $route API documentation.
Side note: This question is answering how to achieve this using ng-Route however I would recommend using the ui-Router for routing. It is more flexible, offers more functionality, the documentations is great and it is considered the best routing library for angular.

You could inject $routeParams to your controller and access all the params that where used when the route was resolved.
E.g.:
// route was: app.dev/backend/:type/:id
function MyCtrl($scope, $routeParams, $log) {
// use the params
$log.info($routeParams.type, $routeParams.id);
};
See angular $routeParams documentation for further information.

Better would have been generate url like
app.dev/backend?type=surveys&id=2
and then use
var type=$location.search().type;
var id=$location.search().id;
and inject $location in controller.

In your route configuration you typically define a route like,
.when('somewhere/:param1/:param2')
You can then either get the route in the resolve object by using $route.current.params
or in a controller, $routeParams. In either case the parameters is extracted using the mapping of the route, so param1 can be accessed by $routeParams.param1 in the controller.
Edit: Also note that the mapping has to be exact
/some/folder/:param1
Will only match a single parameter.
/some/folder/:param1/:param2
Will only match two parameters.
This is a bit different then most dynamic server side routes. For example NodeJS (Express) route mapping where you can supply only a single route with X number of parameters.

ex:
url/:id
var sample= app.controller('sample', function ($scope, $routeParams) {
$scope.init = function () {
var qa_id = $routeParams.qa_id;
}
});

Just inject the routeParams service:
http://docs.angularjs.org/api/ngRoute.$routeParams

Related

Angular UI router Initialising

I am trying to use Angular UI router in my application. When I initialise the UI router instead of getting say, localhost:8000/#/ I get localhost:8000/#!#%2F.
My app.js is as follows:
angular
.module('quiz',['ngMaterial',
'ngMessages',
'ngCookies',
'ngResource',
'quiz.routes'
]).config(function($resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
});
angular
.module('quiz.routes',['ui.router']);
In my quiz.routes.js I have:
(function () {
angular
.module('quiz.routes')
.config(config);
function config($urlRouterProvider,$stateProvider){
$stateProvider
.state('register',{
url: '',
templateUrl: '/static/templates/register.html'
});
}
})();
So instead of the trailing slash I get !#%2F in my URL. Why is this?
Assuming that you are using Angular version 1.6, then this is likely because of the changes made to the default hashPrefix which is now set to !. To fix, you need to inject $locationProvider into your module's config block and reset the default hashPrefix back to the empty string.
$locationProvider.hashPrefix('')
This was reported as a bug here, although it turns out that it was by design and changed intentionally.

Angular - Load custom template using dynamic path with fallback

I want to replace the following code in my routes:
angular.module('app').config ($stateProvider, $urlRouterProvider) ->
.state 'statistics',
controller: 'AppCtrl'
templateUrl: '/app/statistics.html'
By something like this:
angular.module('app').config ($stateProvider, $urlRouterProvider) ->
.state 'statistics',
controller: 'AppCtrl'
templateUrl: Something.resolveTemplatePath('/app/statistics.html')
My goal is to add a prefix based on some configuration, but I need to know if the path with the prefix actually exists.
I need to call this in my routes, so I probably need to put this function is a Provider, right? And I don't really know how to check if the template exists or not. I believe Angular makes an AJAX call to load the template and I saw that I could check if the file is found or not, but I'm not sure what the best solution is.
Because if the file with prefix doesn't exist, then I must load the file without prefix (fallback).
What is the best way to do that? Thanks.
Where would this configuration for the prefix exist? Inside your Angular code or would it be part of a build tool like Gulp/Grunt?
Assuming that this 'prefix' would be an Angular constant by the name TEMPLATE_PREFIX, you could use a combination of $templateCache and the templateProvider given by ui-router to do
templateProvider: Something.resolveTemplatePath('/app/statistics.html')
And the definition of Something as a service as -
angular.module('app').service('Something', function($templateCache, TEMPLATE_PREFIX) {
this.resolveTemplatePath = function(templateURL) {
return $templateCache.get(TEMPLATE_PREFIX + templateURL) || $templateCache.get(templateURL);
}
});
There's a great grunt build task for populating $templateCache - https://www.npmjs.com/package/grunt-angular-templates

Re directing to another page Angularjs

Hi I have am trying to re direct the page to another route with parameter
like this passing id as a parameter.
$location.path('/api/po/'+id);
What is the proper way to re direct to another page using router and parameter? My module, controller etc all are working fine. Just having problem re directing.
Thaks
take a look at this ui router to me is the better way to build a function that move you application from a view to another one. It's really easy to use and very rich of useful method.
Follow these steps
Install ui-router using bower
Include angular-ui-router.js in your index.html
Add 'ui.router' to your main module's list of dependencies
Add a ui-view directive to the some in your html
Set up your states in the module config, following is an example how:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
})
Refer this in case of doubt.

App not working if dependency left blank, working if dependency completely removed

I have a simple Angular app, calling a controller, which in turn calls a service. This service then loops through an array and returns a few strings.
If I leave the dependencies on the angular.module empty in the controller and the service it does not return the array:
app.js
angular.module('list_app', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/list', {
templateUrl: 'views/template.html',
controller: 'ListCtrl'
})
.otherwise({redirectTo: '/list_page'});
});
Controller
angular.module('list_app', [])
.controller('ListCtrl', ['$scope', 'Service', function ($scope, Service) {
Service.getList($scope);
}]);
Service
angular.module('list_app', [])
.factory(
'Service', function Service() {
function getList($scope){
var listRules = $scope.rules=['Test One', 'Test Two'];
var arrayLength = listRules.length;
for (var i = 0; i < arrayLength; i++) {
return(listRules[i]);
}
};
return {
getList: getList
}
});
But if I remove the dependancy [] from the controller and service, it works fine...
Like this:
angular.module('list_app', )...
Can anyone tell me why this is?
Thats because you only need to initialize your module once.
This happens when you use the curly braces:
angular.module('list_app', ['ngRoute'])
Afterwards you dont need them anymore as the module already is initialized.
So afterwards you can just call in all subsequent calls (controller, service):
angular.module('list_app')
Missing Include?
In order to use ngRoute you need to include angular-route before you load your controller. That would be the following (as of right now):
<script type="text/javascript" src="//code.angularjs.org/1.2.14/angular-route.min.js" />
You can also download the minified or full version of this library from the angular site.
Multiple Module Definitions
Another thing I noticed about the code is it looks like you are calling "angular.module" multiple times. You should only do this once, something like:
var list_app = angular.module('list_app', ['ngRoute']);
// define the service as an example:
list_app.factory('MyService', function Routine() {
});
// then define the controller
list_app.controller('MainController, ['$scope', function ($scope) {
}]);
The point is after you define the module once - you should use that reference to make any further declarations! This also might help fix your issue.
Side Note
One more comment is that when you try to inject a dependency that angular can't find the most common error you will see in the console is:
Uncaught Error: [$injector:modulerr] (etc.)
Whenever you see a message like this you should start to look at whether or not you are missing script includes and checking to make sure these are in the correct order.

Can angularjs routes have default parameter values?

Can I set a default value of a parameter of a route in AngularJS? Is there a way to have /products/123 and /products/ handled by the same route ?
I'm looking to refactor my existing code, which looks like:
myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/products/', {templateUrl: 'products.html', controller: ProductsCtrl}).
when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);
function ProductsCtrl($scope, $routeParams) {
$scope.productId = typeof($routeParams.productId) == "undefined" ? 123 : $routeParams.productId;
}
It works, but it's not very elegant. Is there a better way ?
I recognize that this question is old, but still: Why don't you just redirect the "empty" URL to one containing the default productId?
myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/products/', {redirectTo: '/products/123'}).
when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);
AngularJS does not allow default values for route parameters.
But routes (in AngularJS) should not have default parameters.
Resources could have default parameters.
In AngularJS if you want a route with an optional parameter, these are actually two different routes.
Why?
Routes should be simple
Routes does not allow regular expressions matching for parameters
Routes are not something which exposes an API to work in your application (unlike Resources do). Routes are just configuration which connects a URL with a template and a controller. Thus having more routes is better:
It is clear which route maps to which url.
It is more verbose, but simpler to read. Having more complex routes would create a steeper learning curve where AngularJS does not need one.
Unlike server-side frameworks which have routes
AngularJS routes do not have names.
You do not build URLs from the defined routes.
You do not have logic (a.k.a functions) in the routes definitions.
Simpler routes = more lines to define them = less headaches working with them.
NOTE: Please keep in mind the question and this answer are for an old version of AngularJS (1.0 I think) pre-dating the new routes/resources implementation.
I had a similar requirement. What i did was to create a function to resolve. Something like below
myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/products/', resolveProduct()).
when('/products/:productId', resolveProduct())
}]);
function ProductsCtrl($scope, $routeParams) {
$scope.productId = $routeParams.productId;
}
function resolveProduct() {
var routeConfig = {
templateUrl: 'products.html',
controller: ProductsCtrl,
resolve: {
productId: ['$route', function($route){
var params = $route.current.params;
params.productId = params.productId || 123;
}]
}
}
return routeConfig;
}
With url: "/view/:id/:status?", You can indicate an optional parameter.
Just thought someone may need it.
Not sure if this question is specific to $routeProvider but in $stateProvider, you can achieve this by
myApp.config(function($stateProvider) {
$stateProvider
.state('products', {
url: '/:productId',
templateUrl: "/dashboard/products.html",
controller: 'ProductController',
params: {
productId: {
value: "defaultValue",
squash: true // or enable this instead to squash `productId` when empty
}
}
});
});

Categories