Angularjs ui-router add parent url parameter to current state - angularjs

This is my app state
.state('app', {
url: "/?:site_id",
templateUrl: "/controls/angular/templates/partial/app.html",
abstract: true
})
.state('app.popup', {
url: "popup",
templateUrl: "/controls/angular/templates/popup.html",
controller: 'PopupController'
})
The app root (that config as abstract) has parameter (site_id) that I can use in all other pages in the application.
I have drop-down list that can change the site.
How can I add the site url parameter to current page with all other parameters that exist
Just change the root site_id parameter.
var oSelect = $('#site_select_tag').select2();
oSelect.on("change", function (e) {
var curr_site_id = e.val;
$state.go to => ?????????
//scope.site_id = e.val;
scope.onChange()(e.val);
});

Thanks
The solution is simple
$state.go('.', {site_id: e.val})
Keep all other parameters and set the new parameter

You can pass options to the go method of $state:
$state.go(to [, toParams] [, options])
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#stategoto--toparams--options
$state.go('myState', {'myParam': myValue});
And you can set parameters on ui-sref:
ui-sref='stateName({param: value, param: value})'
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
<a ui-sref="myState({'myParam': myValue})">myLink</a>
You can access the current state as $state.current.name and the current parameters as $state.params so what you can do is this:
var params = $state.params;
params.id = 123; // Set new ID
$state.go($state.current.name, params);

If I understand you correctly your trying to manipulate the state data after it is set up in the $stateProvider. If so you should set up your own state provider like Mean.io do
// $meanStateProvider, provider to wire up $viewPathProvider to $stateProvider
angular.module('mean.system').provider('$meanState', ['$stateProvider', '$viewPathProvider', function($stateProvider,viewPathProvider){
function MeanStateProvider() {
this.state = function(stateName, data) {
if (data.templateUrl) {
data.templateUrl = $viewPathProvider.path(data.templateUrl);
}
$stateProvider.state(stateName, data);
return this;
};
this.$get = function() {
return this;
};
}
return new MeanStateProvider();
}]);

Related

How to Redirect to new page in Angular.js with custom url and query string

I want to redirect from PageB to PageA with some queryString to track from which page the user has come using onClick its calling a function 'functionName'
$stateProvider
.state('edit-blog', {
url: '/blog/edit/:a/:b',
templateUrl: 'app/blog/edit/edit-blog.html',
controller: 'EditBlogController',
controllerAs: 'vm',
data: {
permissions: {
only: ['viewEditBlog']
}
}
})
editController.js
function init() {
var search = location.search.substring(1);
if(search){
rObj = parameterizedQueryStringsToObjectFactory.objectGenerator(search);
$location.search(rObj);
dataForFilter = angular.copy(rObj);
}
}
init();
From one controller I want to redirect the user using state.go with addition queryStringParameter let say '?c=c', How to append the c parameter to the url so that it can be captured in the controller 'EditBlogController'?
controllerB.js
vm.functionName= function (ev, a,b) {
$state.go('edit-blog', {a: a, b:b});
};
Append the url parameter:
url: '/blog/edit/:a/:b?c=:c',
and then add c in the object {a: a, b:b, c:c}.

angular ui-router go to URL

How to use $state.go() if I have just the URL ?
Or can I get a state based on URL? (and than use $state.go(state))
I'm asking because I had to intercept the $urlRouterProvider.otherwise() to wait for an other plugin loads some external modules.. and now I need to continue and call the URL that call otherwise()
In place of $state.go(), you can use $location service as well.
i.e.
$location.path(url)
Please take care of not using # in URL. You can also use window.location.href
I had a similar problem, and $location wasn't helping, so I wrote a function to get the state from the url.
NB: I am using nested states based on ui-router.stateHelper, so I traverse my nested states object, testing for url matches. It would be slightly different when using dot notation to define nested states - and even easier if you don't use nested states at all!
function goPath (path) {
var target;
var arr = path.match(/\/\w+/g);
var i = 0;
var testState = function (state, i) {
if (state.url === arr[i]) {
target = state;
if (state.children && state.children.length && arr.length > i+1) {
i++;
state.children.forEach( function (childState) {
testState(childState, i);
});
}
}
};
myStatesObj.forEach( function (state) {
testState(state, i);
});
$state.go(target.name);
};
I was on a similar situation, what I did is changed the location to a different path and reset it to the current after a timeout like this
var path = $location.path();
$location.path("/");
$timeout(function(){
$location.path(path).replace(); //use .replace() so the empty path won't go to the history
},0);
i'm adding a full answer to this due to the high number of views.
NOTE: location.search() is only used where you need to handle a URL with a query string in it. otherwise use location.path() only.
your ui.router login state should look something like ...
.state('login', {
url: '/login',
templateUrl: 'routes/login/login.html',
controller: 'LoginController',
controllerAs: 'loginCtrl',
authenticate: false,
params: {
fwdPath: undefined, // Location to forward to on login success
fwdQueryStringObject: undefined // Query string object to use on login success - retrieved from $location.search()
}
})
your 401 (unauthorised) interceptor should look something like ...
state.go('login', {fwdPath: location.path(), fwdQueryStringObject: location.search()});
your login controllers login function should call your login service's login function. the code INSIDE the controllers login function should look something like ...
loginService.login(self.username, self.password).then(function (response) {
// local vars prevent unit test failure
var fwdPath = state.params.fwdPath;
var fwdQueryStringObject = state.params.fwdQueryStringObject;
if (response.status === 200) {
timeout(function () {
if (fwdPath != null) {
location.path(fwdPath).search(fwdQueryStringObject);
location.replace();
} else {
state.go('home');
}
}, 400);
} else {
self.error = true;
}
self.pending = false;
}
};
and finally your unit tests ...
state.params.fwdPath = '/login/list';
state.params.fwdQueryStringObject = {q: 5};
spyOn(location, 'path').and.callThrough();
spyOn(location, 'search').and.callThrough();
...
expect(location.path).toHaveBeenCalledWith('/login/list');
expect(location.search).toHaveBeenCalledWith({q: 5});

Call action on page loading in angular

I have the following angular code:
application.controller('ImageController', function ImageController($scope, ImageService, ngDialog) {
$scope.open = function (image) {
ngDialog.open({
className: 'modal',
plain: false,
scope: scope,
template: 'image'
});
}
};
On page loading, when the url has the parameters source and key:
http://www.google.pt/?source=1&key=sdfd-sd-sf
I would like to call open and pass an image with:
image.source = 1;
image.key = sdfd-sd-sf;
How can I do this?
UPDATE
I tried to use ngroute:
$routeProvider
.when('/:source?/:key?',
{
controller: "ImageController"
}
)
with the following route:
domain.com/?source=ddf&key=23jf-34j
On ImageController I tried to get the parameters source and key using:
var image = { source: $routeParams.source, key: $routeParams.key };
if (image.source != null && image.key != null) {
open(image);
}
But both source and key are undefined. Any idea why?
If you're using ngRoute, you can inject $routeParams into your controller and simply do:
image.source = $routeParams.source;
image.key = $routeParams.key;
Nice egghead video about it: https://thinkster.io/egghead/routeparams-api/
UPDATE
There's no need to specify query parameter names in when (it's only needed when using paths like domain.com/source/123/key/456), so this is wrong:
.when('/:source?/:key?',
It should be just:
.when('/',
While your URL has the hashbang (or html5mode):
domain.com/#/?source=ddf&key=23jf-34j
then this will work just fine:
var image = { source: $routeParams.source, key: $routeParams.key };
Note that if you're not using ng-view the parameters won't be available due to their async nature, so you need to use this watcher in your controller:
$scope.$on('$routeChangeSuccess', function() {
console.log($routeParams);
});
or, if you inject $route instead of $routeParams, you can use:
$scope.$on('$routeChangeSuccess', function() {
console.log($route.current.params);
});
it will return the same object.
UPDATE 2
After a little research, seems like by far the easiest way to do it is to inject $location service, and simply use:
var params = $location.search();
var image = { source: params.source, key: params.key };
Here is a simple example with html5 mode on (will work with your original URL): http://run.plnkr.co/sElZhTrI4JvGc0if/?source=SomeSrc&key=SomeKey
And the full Plunker: http://plnkr.co/edit/Jxol8e7YaghbNScICHqW

ui-route update url without param

i'm trying to update url without params is it possible ? on my app i created state
.state('webPrint', {
url: '/web/print/:lead',
templateUrl: '/application/views/web-print.html'
})
and when i'm redirecting i'm passing an object
var obj = JSON.stringify(lead);
$state.go('webPrint', { lead: obj });
but my url is something should be like
/web to /web/print but it shows /web/print + "stringify object data" so i changed my code to
$state.go('webPrint', { lead: obj }, { location: false, inherit: false });
but now it's not change url at all. i mean /web to /web
how can i avoid stringify string on url and pass direct to new url?
thanks
You are using option location: false which means you are telling not to change the url.
I would say create a service with getter and setter to save and retrieve your data like below
angular.module('app.service').factory('leadService', function(){
var lead = {};
return{
getLead : function(){
return lead;
},
setLead: function(data){
lead = data;
}
}
});
.state('webPrint', {
url: '/web/print',
templateUrl: '/application/views/web-print.html'
})
var obj = JSON.stringify(lead);
leadService.setLead(obj);
$state.go('webPrint');
Then in your controller get the lead Object using
var lead = leadService.getLead();

State parameters outside of the url?

Is there a way to pass parameters to a state without them being represented in the url?
Let's say I have the following state:
.state('accounts.content.viewaccounts.details.contacts.edit', {
url:'/edit/{contactId:[0-9]{1,10}}',
templateUrl: 'app/common/templates/StandardForm.html',
resolve: {blahblah}
Is there a way for me to send an optional parameter to this state, when navigating to it with $state.go, without adding it into the url?
You can use shared properties service and pass elements between controllers:
.service('sharedProperties', function () {
var item = null;
return {
getItem: function () {
return item;
},
setItem: function(value) {
item = value;
}
}});
Then before you move to controller you use:
sharedProperties.setItem(your-item);
and after you load the new controller you use:
var model = sharedProperties.getItem();
No. Not without using something like a service. see #Liad's answer

Resources