AngularJS: Pass Parameter through URL - javascript

I have a AngularJS Application in different languages.
Now I want to preselect a language, when the user calls the site, with following string at the end:
/en, /de, ...
Is this even possible in AngularJS? I also can use some other syntax, if this is needed.
Thank you very much!

If you are wanting to get something from the url to run logic on (i.e. /de in the url)
you can use the $location object
Angular location
If you are wanting dynamic urls so that things like /de, /fr, /es go to the same page/view, you'll need to use the $route object
Angular routes

With the limited amount I could understand from your question..
var app=angular.module("angularapp",['ngRoute']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/',{
redirectTo: '/en'
})
.when('/:language',{
//do something
});
}]);
you can then get access to {"language":"en"} object

Related

AngularJS: Dynamic URL Prefix

I have a large angular app that lives at a URL like so:
http://myangularapp.com/app/index.html#/
The URL I intend on giving out will need a name injected into the URL as this one site will support multiple users.
So, without modifying any directory structure, I'd like to do:
http://myangularapp.com/app/bob/index.html#/
and also:
http://myangularapp.com/app/harry/index.html#/
All my controllers and functionality would ideally stay the same.
Super stumped on this one!
Use the $routeProvider service. You can define where urls go, like so.
$routeProvider.
when('/app/foo/bar/what/about/bob', {
templateUrl: 'app/bob/index.html', <---directory and url don't have to match
controller: 'bobController'
}).
when('/app/harry', { ...
})

AngularJS - Handling empty Params

I'm using UI-Router and all is working great but I'd like to prevent the possibility that someone could access a page with empty Params. Is there a "best" method for preventing something like... '/person//info' where it would normally expect an id for the person like '/person/23/info'. My setup is as follows...
.state('person',{
abstract:true,
url:'/:id/',
templateUrl: '/assets/components/views/person.html',
controller: function($stateParams){
console.log($stateParams.id);
}
})
The reason this is a real pain is because if you hit the path '/person//info', it will redirect to /person/info essentially breaking the app

Angularjs - dynamic pages, same template, how to access and load article by id

I am slightly puzzled on how to use angularjs to build a blog-like web site.
If you think of an ordinary blog,,, and say,, I am building it using php and mysql.. what I don't understand is how do I make angular get an article based on id..
I can load data for a list of all articles.. I can load data for a single page (from a static json),, I understand how to send http requests,, but how do I access
mysite.com/page?id=1 or
mysite.com/page?id=2 or
mysite.com/page?id=3
Obviously, I want to load the same template for each separate blog post.. but I have not yet seen a single example that explains this simply.
If I have three posts in my database with id 1,2,3 how is angular meant to generate links to each individual article? I understand that I can load data to assemble urls but what urls? I suppose I am confused with routing.
Could you recommend a SIMPLE and understandable example of this? Could you suggest how to think about this?
Thanks!
In this short explanation I will use examples based on official tutorial.
Propably somwhere in your application you created controllers module with code close to that:
var blogControllers = angular.module('blogControllers', []);
// other controllers etc.
blogControllers.controller('BlogPostCtrl', ['$scope',
// more and more of controller code
We will be back here in a moment :) If you have controllers module, you can create a route linked to the specific controller:
var blogApp = angular.module('blogApp', [
'ngRoute',
'blogControllers'
]);
blogApp .config(['$routeProvider',
function($routeProvider) {
$routeProvider.
// other routes
when('/post/:postId', {
templateUrl: 'partials/blog-post.html',
controller: 'BlogPostCtrl'
}).
// other...
}]);
Well but what we can do with this :postId parameter? Lets go back to our controller:
blogControllers.controller('BlogPostCtrl', ['$scope', '$routeParams', 'BlogPost',
function($scope, $routeParams, BlogPost) {
$scope.post = BlogPost.get({postId: $routeParams.postId});
}]);
As you see, we are passing $routeParams here and then our BlogPost resource (it will be explained). Simplifying (again), in $routeParams you have all the params that you put in the $routeProvider for exact route (so :postId in our example). We got the id, now the magic happens ;)
First you need to add services and/or factories to your app (and look, we are using ngResource):
var blogServices = angular.module('blogServices ', ['ngResource']);
blogServices.factory('BlogPost', ['$resource',
function($resource){
return $resource('action/to/get/:postId.json', {}, {
query: {method:'GET', params: { postId: 'all' }, isArray:true}
});
}]);
Now you know what is our BlogPost in controller :) As you see default value for postId is "all" and yes, our api should retrieve all posts for postId = "all". Of course you can do this in your own way and separate this to two factories, one for details and one for list/index.
How to print all of the blog names? Quite simple. Add list routing without any special params. You already know how to do this so let's skip it and continue with our list controller:
blogControllers.controller('BlogListCtrl', ['$scope', 'BlogPost',
function($scope, BlogPost) {
$scope.blogPosts = BlogPost.query(); // no params, so we are taking all posts
}]);
Voila! All posts in our $scope variable! Thanks to this, they are accessible in the template/view :) Now we just need to iterate those posts in our view, for example:
<ul class="blog-posts">
<li ng-repeat="blogPost in blogPosts">
{{blogPost.title}}
</li>
</ul>
And this is it:) I hope you will find AngularJS quite easy now!
Cheers!
I think what you want to use for this is $routeParams. Have a look at this video from egghead.io which explains how to use it:
http://egghead.io/lessons/angularjs-routeparams
It's a good practice to use hash navigation. So your routing should look like this
mysite.com/blog/#!/id=1
mysite.com/blog/#!/id=2

Pass URL to as $routeParam in AngularJS app

How can I pass actual URL (with slashes, commas, etc.) as a $routeParam to AngularJS App?
this will work:
http://paprikka.github.io/le-bat/#/preview/asdadasda
this won't:
http://paprikka.github.io/le-bat/#/preview/http://page.com
neither will this:
http://paprikka.github.io/le-bat/#/preview/http%3A%2F%2Fpage.com
or this:
http://paprikka.github.io/le-bat/#/preview/?url=http%3A%2F%2Fpage.com
Details
AngularJS routing mechanism by its design does not allow to pass strings with slashes as query parameters. I can understand the reasoning behind this decision - we don't want to create a stateless server here.
However, there are still cases when using different separators or regular expressions in routes might be necessary.
I wanted to create an app that takes a url hash string parameter and loads its content to an iframe (link here). Routes are set up in pretty standard way (I'm using Coffeescript, but this snippet does not differ from pure js):
$routeProvider
.when('/preview/:src', {templateUrl: 'partials/preview.html',
controller: 'PreviewCtrl'})
.when('/preview', {templateUrl: 'partials/preview.html',
controller: 'PreviewCtrl'})
Of course, I can load url from hash before AngularJS gets bootstrapped and then pass it to the library, but it would be nice if I could also update current route parameter when changing data in scope - that's why I think it's much better not to avoid AngularJS API.
Using $routeProvider in Angular 1.2, you can pass in a url if it's at the end of the path by adding an asterik to the pattern. The following should work whether or not you URLComponentEncode the url.
The route:
angular.module('angularApp', ['ngRoute'])
.when('/frame/:picture_url*', {
templateUrl: 'views/frame.html',
controller: 'PictureFrame'
});
The controller:
.controller('PictureFrame', function($scope, $routeParams, $sce){
//whitelist the URL
$scope.picture_url = $sce.trustAsResourceUrl($routeParams.picture_url);
});
Then in your template:
<iframe ng-src="{{picture_url}}"></iframe>
Ok, I've managed to find a solution working with current stable version (#1.0.7).
Current way of handling this problem will involve $route-related events, parsing angular-incompatible urls on the fly and handling them via an additional service working in a similar way as $http interception.
You can see working code examples here: http://embed.plnkr.co/fIA2xj/preview
Main steps
pass an angular-incompatible url as usual, eg. go to site.com/url/http://site.com
listen to a $routeChangeStart event and extract correct url parameter for paths beginning with /url/
encode the correct url parameter to an angular-compatible form (in this particular case, I use base64). Don't use encodeURIComponent, because angular will treat as any other url
redirect to another route with your business logic, eg. site.com/parsed-url/BASE64_GOES_HERE
decode the URL in the controller and use it as usual :)
Code
Create angular app module as usual
angular.module('routes',[]).config([
'$routeProvider',
function($routeProvider){
$routeProvider
.when('/test', {templateUrl: 'test.html'})
// This one is important:
// We define a route that will be used internally and handle
// parameters with urls parsed by us via the URLInterceptor service
.when('/parsed-url/:url', {templateUrl: 'url.html', controller:'URLCtrl'})
.when('/', {redirectTo: '/test'})
.otherwise({templateUrl: '404.html'});
}
])
URL Interceptor service (singleton)
.service('URLInterceptor', function($rootScope, $location){
// We listen to $routeChangeStart event and intercept it if
// the path matches our url scheme. In this case, every route
// beginning with /url/ will be caught
$rootScope.$on('$routeChangeStart', function(e, next, current){
// $location.path does change BEFORE actual routing happens,
// so in this case we get parsed new location object
// for free.
// To be hones, a better way of handling this case might be using
// $locationChangeStart event instead, but it would require us to parse urls
// manually.
var path = $location.path();
// check if string begins with '/url/'
var matcher = path.slice(0,5);
var cleanPath = '';
if (matcher === '/url/'){
// Yes it does, yay!
// Remove leading '/url/' to extract the actual parameter
cleanPath = path.slice(5);
// Encode our url to a safe version. We know that encodeURIComponent won't
// work either, so a good choice might be base64.
// I'm using https://code.google.com/p/javascriptbase64/downloads
$location.path('/parsed-url/' + Base64.encode(cleanPath));
// Prevent default event execution. Note that, it won't cancel related $location Events
e.preventDefault();
}
});
return {
decode: Base64.decode,
encode: Base64.encode
}
})
Controllers
// Main application controller
// We instantiate our URLInterceptor service here
.controller('AppCtrl',function($scope, $location, URLInterceptor){
$scope.navigateTo = function (path) {
$location.path('/url/' + path);
}
})
.controller('URLCtrl', function($scope, $routeParams, URLInterceptor){
$scope.url = URLInterceptor.decode($routeParams.url);
});
Two things you should remember:
Although I tried to create a solution as clean as possible, usually passing the data this way to angular isn't considered a good practice, so try not to use it unless you really need to.
You can handle this issue with only one route. I just find it cleaner this way.
I have a solution but I don't know if it will help you. From Angular documention http://docs.angularjs.org/api/ng.$location $location has a function search(search, paramValue)
To pass the parameter:
parameter = encodeURIComponent url
$location.search({ yourURLParameter: parameter }).path('/preview')
To read the parameter:
url = decodeURIComponent $location.search().yourURLParameter
Of course you need to inject $location dependency
I have mixed search params with routes. Your search needs to come before your routes.. specifically for older browsers. I think ie7 blows up if its not url/?search/#/hash
Try this format:
domain.com/?my=params&another=param/#/my/hashes

AngularJS codes structure. Are they any difference?

New in angularJS, I would like to know what are the pros and cons between the codes below?
Which is recommended to use?
$routeProvider.when('foo', {
templateUrl: 'foo.html',
controller: fooCtrl
function fooCtrl() {
//something here
}
});
or
$routeProvider.when('foo', {
templateUrl: 'foo.html'
});
app.controller("fooCtrl", function() {
//something here
});
//in html
<div ng-controller="fooCtrl"></div>
I prefer the second approach, and use it when developing our application.
It is the elegant way of coding , seperating your routes-configuration, module-wiring etc from the Controllers. we can write the routes-config in a main file say app.coffee [I use coffeescript] defining like
routesConfig = ($route) ->
$route.when('/employees',
{templateUrl: 'employee.employeeView.html'})
Define the routesconfig and wiring modules [eg: employee.employeeController] here.
modules = ['employee.employeeController', 'user.userController']
you can create, start your angular application from here,
m = angular.module('app', modules)
m.config['$route', routesConfig]
Now you can specify the Controllers seperately, say in employeeController.coffee
name = 'employee.employeeController'
mod = angular.module(name, [])
mod.controller(name, [
'$scope'
'$log'
($scope, $log) ->
$scope.name = 'java'
In your View, say employeeView.html
<div ng-controller="employee.employeeController">
<div class ="info">
Name is {{name}}
</div>
Basically we seperated Controllers, View , application configuration from each other.
To add something specific to your question,
If you are using the first approach, then probably you are using your controller as a Route Controller, and in
second approach , it is a View Controller.
In both cases, controller will be instantiated for the mentioned route.
For instance, I have a main page index.html and i am adding many views (ng-view) in the basic html template.
If you have two different sections of view in this template say 'section1' and 'section2' and each of them are included
with ng-view, then you probably need two different controllers, and is good to define them using the second approach.
Use this type of controller to initialize the scope with data,functions,watches etc and refer the controller in your view using ng-controller.
If you have a section, say 'section1' [representing the main html page] that is included via ng-view which encapsulates both section1 and section2,
then that view needs route controller.
Do not use both the approaches for a single view/route as it would result in creating two instances of same controller
for the same route.
I like to add two links here which eloborates this (your query) and address this query (problem in defining controllers in two places)
https://groups.google.com/forum/?fromgroups=#!topic/angular/52zE0ibOAgk
AngularJS can a $on method be called more than once for a single $broadcast?

Categories

Resources