How generate url in angular ui-router and put it to location - angularjs

View has controls for selecting cities and selecting params. And this view show selected objects for the selected cities. When view is loaded I parse the url and do request to the server. Url for the view are some as: http://example.com/cities?cityId=3&cityId=33&param1=value1. My questions:
how can I put that url in location?
how can I handle changed url in location?
in which event I must hang the handler?

You can generate URL with
$location.url('cities?cityId=3&param1=value1');
and You can handle this in your router config $stateProvider where you define states
.state('cities', {
url: "/cities?cityId&param1",
templateUrl: "....",
controller: "citiesController"
})
// will match to url of "/cities?cityId=[any id]&param1=[any value]"
and finally You can have these parameters in the citiesController.js i.e
console.log($stateParams);
//Object {cityId: "3", param1: "value1"}
Hope it helps.

Url generating automatically by $state.go('cities', {/* params */}, {location: true}).
In controller I put handler in $scope.$on('$stateChangeSuccess'..

Related

How to pass data to other controller in Angular js?

I have 2 controllers, I want to have next thing:
when I click on item in controllerOne it should highlight element with the same ID in controllerTwo.
I have highlighting method But how to send event with ID from controllerOne to controllerTwo ??
Keep the shared data in a service that's accessible from both controllers, see https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#defer-controller-logic-to-services
Use $route to pass variables in the URL:
/controller2route/:action/:id
for example:
/details/highlight/2
You can then use ifs and switches to call the appropriate function, for example highlight(2) for the above URL.
https://docs.angularjs.org/api/ngRoute/service/$route
You can you route parameter in routing.
In routing
app.config(function($routeProvider) {
$routeProvider
.when("/users/:userId", {
templateUrl : "main.htm",
controller:"controllerTwo "
})
})
and in controllerTwo use $routeParams to get the user id.
app.controller('controllerTwo',function($scope,$routeParams){
var userId = $routeParams.userId;
})
and the one better solution is to use services. Here is the link
https://thinkster.io/a-better-way-to-learn-angularjs/services

Angular UI Router Wrong Template And Controller

I have an odd issue where I use an ng-click to $state.go() to a state, and get the correct url but the wrong template and controller.
These are my states:
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/messages");
$stateProvider.state('message', {
url: "/messages/:to/:fro/:messageID",
templateUrl: 'message.html',
controller: 'MessageCtrl'
}).state('compose', {
url: "/messages/compose/a/message",
templateUrl: 'compose.html',
controller: 'ComposeCtrl'
});
});
This is the function triggered by my ng-click and I am in fact getting the console log so I know the right one is firing.
$scope.composeMe = function(){
console.log("You want to compose a message!");
$state.go("compose");
};
When I fire that function I get the url to change to http://example.com/messages/compose/a/message but I get the templateUrl and the controller of the message state.
Why is that? The other state is fired from a similar (ng-click derived) function and works perfectly.
The URL you are trying to go to matches the one you are actually going to.
How would ui-router know that "compose" isn't the to: field you want, "a" isn't the fro: field you want, and "message" isn't the messageID you want?
Move the more specific state definition above the one with URL parameters.

Angular UI router dynamically inject URL to html

I am trying to build a simple app, which goes the following way:
I have 2 menu items in the navbar: home and contact.
The home should be a unique URL only once from the server, at initialisation, read from a QR code (i got this covered, that is no problem to me) and the contact should always be the same.
I got the contact done in the following way:
$stateProvider.state('contact', {
url: '/contact',
templateUrl: 'src/views/contact.html',
controller: 'contactController'
})
The problem is with the home, which should keep the unique URL received by the server. How should i write the state for that one?
.state('home', {
url: '/:uid',
templateUrl: 'src/views/home.html',
})
Also, the home should keep it's unique url generated by the server after refresh and while navigating from contact to home.
In the HTML i would have something like
<a ui-sref="home({uid: --some dynamic uid?--})">Home</a>
this is the part which also requires help.
Set the home state to
.state('home', {
url: /{uid},
templateUrl: 'src/views/home.html',
})
and you could grab the parameters by injecting $stateParams into the controller. $stateParams.uid would return the parameters and store that in local storage or cookies.
Check this link out
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
UPDATE:
for example, this is the sample controller that is attached to the home page
app.controller('homeCtrl', function($stateParams) {
var id = $stateParams.uid; //this is how you retrieve the uid
});
by going to your home page e.g. http://www.example.com/abcd12345, the above $stateParams.uid would return abcd12345
Now to set the url. simply use ui-sref instead of href on the <a> tag. ui-router will automatically generate href for you.
e.g.
<a ui-sref="home({uid:'abcd12345'})">Home</a>
You have to create a custom provider and inject it into the config.
eg:- .config($stateProvider, $urlRouterProvider,yourprovider) .
I am not sure about this. But please check this way too..

AngularJs UI-Router - Page Refresh $state.current is now empty

I have an Angular application using ui-router and I am having issues whenever I refresh the page. I am using nested views, named views to build the application. Whenever I refresh the page, ui-router doesn't reload the current state and just leaves the page blank.
On page load $state.current is equal to
Object {name: "", url: "^", views: null, abstract: true}
I am reading my navigation from a .json file via $http and looping through the states. So this is what I can show:
stateProvider.state(navElement.stateName, {
url: navElement.regexUrl ? navElement.regexUrl : url,
searchPage: navElement.searchPage, //something custom i added
parent: navElement.parent ? navElement.parent : "",
redirectTo: navElement.redirectTo,
views: {
'subNav#index': {
templateUrl: defaults.secondaryNavigation,
controller: 'secondaryNavigationController as ctrl' //static
},
'pageContent#index': {
template: navElement.templateUrl == null
? '<div class="emptyContent"></div>'
: undefined,
templateUrl: navElement.templateUrl == null
? undefined
: navElement.templateUrl,
controller: navElement.controller == null
? undefined
: navElement.controller + ' as ctrl'
}
}
});
This code gets executed for each item in the nested json object. If there is anything else that would be helpful, let me know.
There is a question: AngularJS - UI-router - How to configure dynamic views with one answer, which shows how to do that.
What is happening? On refresh, the url is evaluated sooner, then states are registered. We have to postpone that. And solution is driven by UI-Router native feature deferIntercept(defer)
$urlRouterProvider.deferIntercept(defer)
As stated in the doc:
Disables (or enables) deferring location change interception.
If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call $urlRouter.listen() after you have configured your own $locationChangeSuccess event handler.
In a nutshell, we will stop URL handling in config phase:
app.config(function ($urlRouterProvider) {
// Prevent $urlRouter from automatically intercepting URL changes;
// this allows you to configure custom behavior in between
// location changes and route synchronization:
$urlRouterProvider.deferIntercept();
})
And we will re-enable that in .run() phase, once we configured all dynamic states from JSON:
.run(function ($rootScope, $urlRouter, UserService) {
...
// Once the user has logged in, sync the current URL
// to the router:
$urlRouter.sync();
// Configures $urlRouter's listener *after* your custom listener
$urlRouter.listen();
});
There is a plunker from the linked Q & A
I don't know how are all your routes.. but if you refresh a page of a child state, you need to pass all parameters of the parents states to be resolved correctly.

How not to change url when show 404 error page with ui-router

I want to show 404 error page, but also I want to save wrong url in location.
If I'll do something like that:
$urlRouterProvider.otherwise('404');
$stateProvider
.state('404', {
url: '/404',
template: error404Template
});
url will change to /404. How I can show error message on wrong urls without changing actual url?
There is solution for this scenario. We'd use 1) one ui-router native feature and 2) one configuration setting. A working example could be observed here.
1) A native feature of ui-router state definitions is:
The url is not needed. State could be defined without its representation in location.
2) A configuration setting is:
otherwise() for invalid routes, which parameter does not have to be a string with default url, but could be a function as well (cite):
path String | Function The url path you want to redirect to or a function rule that returns the url path. The function version is passed two params: $injector and $location
Solution: combination of these two. We would have state without url and custom otherwise:
$stateProvider
.state('404', {
// no url defined
template: '<div>error</div>',
})
$urlRouterProvider.otherwise(function($injector, $location){
var state = $injector.get('$state');
state.go('404');
return $location.path();
});
Check that all in this working example
As of ui-router#0.2.15 you can use $state.go() and send option not to update the location:
$urlRouterProvider.otherwise(function($injector) {
var $state = $injector.get('$state');
$state.go('404', null, {
location: false
});
});

Resources