how do I find everything left of a certain character? - javascript

Is it possible to get everything from the left of a "/" in a templateURL string from angular routing.
For example:
var app = angular.module('demoApp', ['ngResource', 'ngRoute'], function ($routeProvider){
$routeProvider
.when('/',{templateUrl: 'directoryName/pageName.html', controller: 'mainCtrl'});
});
Using templateURL property "directoryName/pageName.html" I would like to get "directoryName"
How can I achieve this?

Use regex!
var regex = /([^\/]*)\//;
var stripped = regex.exec('#some/string/with/stuff')[1];
This gives you back '#some'
EDIT
As far as getting this in your code, you can use the $routeChangeSuccess event on $rootScope to get the route out and use that string somewhere else
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
// Use what #Dalorzo suggests
var pathName = current.$$route.templateUrl.split('/')[0];
// Do something with pathName ...
});

You can use the current object of the $route service inside your controller to get the current route object. This way, to access the templateUrl property you just need to use : $route.current.templateUrl.
Now that you have this string, you can use split('/') on it to get a array of tokens inside the URL that are separated by a /.
Finally, to use it in your template, you just need to inject this value inside your $scope.

Related

angularJS set route params in controller

I have an app which creates several surveys with random survey ids. As the ids are generated in the backend they are set in the controller. I read the documentation on that, however I do not really understand how to set the routeparams in order to always reach the page /survey/:surveryID.
Here is my code so far:
App Config:
...
.when('/survey/:surveyId', {
templateUrl: 'views/survey.html',
controller: 'SurveyCtrl',
controllerAs: 'survey'
})
Controller:
function SurveyCtrl($scope, RequestService, _, $location, $routeParams) {
$scope.go = function () {
$location.path('/#/survey/' + Math.random());
};
}
View with the link to /survey/:surveyId:
<div>
<md-button ng-click="go()">Enter Survey</md-button>
</div>
I know that this is not the right way and it is not even working. Can someone tell me how to dynamically create these params and set them in the controller so I can access the link with a button and then when clicked reach the survey/:surveyId page?
To get your work done,
$location.path('/survey/' + Math.random());
You can use search method to pass params as well,
$location.path('/myURL/').search({param: 'value'});
$location methods are chainable.
this produce :
/myURL/?param=value
You could also use the updateParams method for that:
$route.updateParams({'surveryID': Math.random()});
And access the data using $routeParams.surveryID

Angularjs - Get URL parameters from inside the when() function

Given the following code:
$routeProvider.when('/movies/:type', {
title: 'Movies',
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl'
});
How can I access the :type param from inside the when function? I want to do something like so:
$routeProvider.when('/movies/:type', {
title: 'Movies' + ' - ' + :type,
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl'
});
That value in title must be dinamically generated.
Thanks in adv.
I'm not sure why you are extending the route (config) object, but you are able to access routeParams from within your controller. That is also the recommended way.
The $routeParams service allows you to retrieve the current set of route parameters.
angular.module('MyModule').controller('MoviesCtrl',function($scope, $routeParams) {
$scope.currentMovieType = 'Filmes-' + $routeParams.type;
});
Let's say your route is something like that /movies/scifi. In this case $scope.currentMovieType becomes scifi and you can use {{currentMovieType}} in your view to populate this value. You can find detailed informations in the documentation.
Note that the $routeParams are only updated after a route change completes successfully. This means that you cannot rely on $routeParams being correct in route resolve functions. Instead you can use $route.current.params to access the new route's parameters.
It is not really possible, because the route config object is not as dynamic as you think. Whatever you put in the route configuration object, it cannot depend on the value that the route param is going to take in the future. Think of how this code gets executed : the configuration object will be evaluated only once, when the route is configured.
On the other hand, if you want to change the page's title when going through this route, you can do it using the $routeParamsservice to access the param value, and the $document service to change the page's title, either in a controller or in a resolveclause.
An example with the latter option:
$routeProvider.when('/movies/:type', angular.extend({
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl',
resolve: {
title: ['$routeParams','$document', function ($routeParams, $document) {
var title = 'Filmes-' + $routeParams.type;
$document.title = title;
return title;
}]
}
}, routeParams));
That works also in a controller of course.
Some notes on your code :
I'm not even sure that there is a point setting a title property in a route config object, I don't see it in the documentation at least.
That second argument routeParams in that angular.extend call - the name is confusing, one could mistake it for the $routeParams service. I think you should call it routeDefaults or something like that instead.
Give a try to $location.absUrl(); requires some calculation too .
https://docs.angularjs.org/api/ng/service/$location

Angular $routeParams force variable type

In my Angular app, I have routes like /items/:id
$routeProvider
.when('/items/:id', {
templateUrl: 'views/items.html',
controller: 'ItemCtrl'
})
In ItemCtrl I get :id with $routeParams.parcId The problem is it's a string while the value is a number and all my id are numbers.
So how to force the correct type and not having string by default?
ps: I don't want to do var id = Number($routeParams.parcId) in all my controllers
I did it using the $routeChangeStart event.
In your app.js file, add the following line to the .run function as :-
angular.module('test1App').run(function ($rootScope) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (next.params.hasOwnProperty('id')) {
next.params.id = Number(next.params.id);
}
});
});
Description: On every change of route, it checks if there is a parameter named 'id'. If yes then it changes it to a number.
Hope it helped.
You need to use resolve in routes and update the variable. Then use this resolved variable in controller
Example
did you try like this?
parseInt($routeParams.parcId)

Angular reload Template + Controller without using Routes

I want to reload a template and the connected Controller without using $routeProvider, because
my Path-structure doesn't fit with .when(...). I want to use $location.path() to read the URL and set the desired action.
But: if the path of the URL changes, the template doesn't automatically update and neither is the controller reloaded.
Is there a way to say something like this?
angular.module('myApp').controller('ctrl').reload()
I would suggest looking into the Angular UI Router written by the same guys who wrote angular. It will let you transition to different states which is what it sounds like you are trying to do.
https://github.com/angular-ui/ui-router
My solution: don't use Routes! Simply update a variable for your template, controllers don't need updates (simply update the data):
angular.module('myApp',[])
.run(['$rootScope', '$location', 'myService', function ($rootScope, $location, myService) {
$rootScope.view = "";
// Some function to read the URL
$rootScope.setRouting = function(){
var p = $location.path().split("/");
// Do things with p[0], p[1], ...
// e.g. if url is /post/123
$rootScope.view = p[0];
myService.setData(p[1]);
}
// Monitor Location changes:
$rootScope.$on('$locationChangeSuccess', function(event) {
$rootScope.setRouting();
});
// And this is useful for calling within template: ng-click="go('...')"
$rootScope.go = function(path){
$location.path(path);
}
}]);
And for the HTML:
<body>
<ng-include src="view + '.html'"></ng-include>
</body>

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

Categories

Resources