How to use aliases in ui-router? - javascript

I am using angular ui for routing in angular js.
I have a url like http://servername/#/news/14.But I want to use aliases and have url like http://servername/#/news/news_title. Is it possible in angular ui??
Here is my config
angular.module('News', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('news', {
url: "/news",
templateUrl: "modules/news/views/news.html",
controller: 'NewsCtrl'
})
.state('news.detail', {
url: '^/news/:id',
views: {
'#': {
templateUrl: 'modules/news/views/news_detail.html',
controller: 'NewsDetailCtrl'
}
},
});
})

Of course it is possible. But to make it happen, you need to somehow map the news_title to 14 which i guess is an id. You can write something like:
$stateProvider
.state('news', {
url: "/news/:news_title",
templateUrl: 'news.html',
...
})
in this case, you can type url like http://http://servername/#/news/latest_bbc_news, in your controller you can get the :news_title by using $stateParams
how you gonna map the news_title to 14 depends on your model.
update
For example you probably can write something like this:
$stateProvider
.state('news', {
url: "/news/:news_title",
templateUrl: 'news.html',
resolve : {
news_item: function(NewsService, $stateParams) {
return NewsService.getByTitle($stateParams.news_title);
},
},
controller:['$scope','$state','news_item',
function ( $scope , $state , news_item){
$scope.news_item= news_item;
}]
})
then in your NewsService you need to implement the method getByTitle to either get the news by title from backend directly, or you fetch all news from backend and cache it in a variable like
var news = [
{ID: 1, Title : 'A', Content : 'XXXXXXXXXXXXXXXXXXXX',},
{ID: 2, Title : 'B', Content : 'YYYYYYYYYYYYYYYYYYYY',},
];
and you have to write your own code to loop through it and find the news you need by title.
Again, ui-router is just setting up the routing rules for you, it is always your responsibility to serve the correct content. I mean ui-router have no idea which news have id 14 and the corresponding title, it can only be fetched from backend and processed by you.

Related

angular uirouter opens wrong url

I'm new to Angular 1 and have to implement a new feature on an existing webapp. The app uses jhipster to generate some parts of the backend and frontend (Angular 1 and uirouter).
So I tried to use my own route and state like this which is mostly copy and pasted from existing components of the webapp:
(function() {
'use strict';
angular
.module('artemisApp')
.config(stateConfig);
stateConfig.$inject = ['$stateProvider'];
function stateConfig($stateProvider) {
$stateProvider
.state('model-comparison-exercise-for-course', {
parent: 'entity',
url: '/course/{courseid}/model-comparison-exercise',
data: {
authorities: ['ROLE_ADMIN', 'ROLE_TA'],
pageTitle: 'artemisApp.modelComparisonExercise.home.title'
},
views: {
'content#': {
templateUrl: 'app/entities/model-comparison-exercise/model-comparison-exercise.html',
controller: 'ModelComparisonExerciseController',
controllerAs: 'vm'
}
},
resolve: {
translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
$translatePartialLoader.addPart('modelComparisonExercise');
$translatePartialLoader.addPart('exercise');
$translatePartialLoader.addPart('global');
return $translate.refresh();
}],
courseEntity: ['$stateParams', 'Course', function ($stateParams, Course) {
return Course.get({id: $stateParams.courseid}).$promise;
}]
}
});
}
})();
Then I try to open this route with the following code:
<a ui-sref="model-comparison-exercise-for-course({courseid:course.id})"
data-translate="artemisApp.course.modelComparisonExercises"></a>
By clicking on that link a http get request is fired which returns a http status code 404: http://localhost:8080/app/entities/model-comparison-exercise/model-comparison-exercise.html
Actually, the url that should be opened is http://localhost:8080/#/course/1/model-comparison-exercise
Any idea what I could have configured wrong?
Please try changing 'content#' to 'content#artemisApp'.
As explained here:
The symbol before the # is the name of the view you want to match, and the symbol after the # is a reference to the state in which the template the ui-view directive should exist in.
And the <a> tag is not being closed:
<a ui-sref="model-comparison-exercise-for-course({courseid:course.id})"
data-translate="artemisApp.course.modelComparisonExercises"></a>
Searching through the code, I found that model-comparison-exercise.html does not exist in folder model-comparison-exercise. Besides model-comparison-exercises.html exist.

AngularJS - $stateProvider when user put wrong URL

I'm new angularjs student.
I'm using state provider in my project, i don't want to change this. Because the code is done.
Here is my code:
function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when('/SecondMain', '/SecondMain/OtherPageOne')
.when('/Main', '/Main/PageOne')
.otherwise("/notfound")
$stateProvider
.state('Main', {
abstract: true,
url: "/Main",
templateUrl: "/templates/Common/Main.html"
})
.state('SecondMain', {
abstract: true,
url: "/SecondMain",
templateUrl: "/templates/Common/SecondMain.html"
})
.state('notfound', {
url: "/NotFound",
templateUrl: "/templates/Common/NotFound.html"
})
.state('Main.PageOne', {
url: "/Main/PageOne",
templateUrl: "/templates/Main/PageOne.html"
})
.state('Main.PageTwo', {
url: "/Main/PageTwo",
templateUrl: "/templates/Main/PageTwo.html"
})
.state('SecondMain.OtherPageOne', {
url: "/SecondMain/PageOne",
templateUrl: "/templates/SecondMain/OtherPageOne.html"
})
.state('SecondMain.OtherPageTwo', {
url: "/SecondMain/PageTwo",
templateUrl: "/templates/SecondMain/OtherPageTwo.html"
})
angular
.module('inspinia')
.config(config)
.run(function ($rootScope, $state) {
$rootScope.$state = $state;
});
}
I want a logic like this: If the user put:
/Main/PageThree
This page does not exist, but the user start URL with
/Main
so that he need to go to -> /Main/PageOne
if the user put:
/Ma/PageOne
/Ma does not exist, the user starts URL totally wrong, so that he goes to -> /Notfound Basically if the user put /Main/WRONG_LINK, he go to /Main/PageOne . And if he does not start with /Main, he go to NotFound.
Can anyone help me please?
Thanks a lot!!!
You are missing this configuration
$urlRouterProvider.otherwise('/NotFound');
Just add this line if no matching route is found then it will redirect you to the /NotFound url
This answer is inspired by this answer.
First of all, you will have to make the Main state non-abstract, so that it can be visited. Then, you can write config related to where you want to redirect (for example, I've used redirectTo with the state):
$stateProvider
.state('Main', {
redirectTo: "Main.PageOne",
url: "/Main",
templateUrl: "/templates/Common/Main.html"
})
// ... Rest of code
So, whenever the URL is changed to /Main, this state will get activated. The second config will be to create a listener for $stateChangeStart event as follows:
angular
.module('inspinia')
.config(config)
.run(function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(evt, to, params) {
if (to.redirectTo) {
evt.preventDefault();
$state.go(to.redirectTo, params, { location: 'replace' })
}
});
});
Now, if a URL like /Ma/* is hit, it automatically be redirected to /NotFound. And if a URL like /Main is hit, it will redirect to /Main/PageOne.
You can follow up on further discussion on this link for any kind of troubleshooting.
Clearly read the statements below
Why are you using this line?
when('/Main', '/Main/PageOne')
For your redirection problem, have a look at the below state
.state('Main', {
abstract: true,
url: "/Main",
templateUrl: "/templates/Common/Main.html"
})
abstract: true ==> This denotes that this particular state is an abstract which can never be activated without its child.
SOURCE: ui-router js code. Refer the below snippet
Since you have this main state as abstract, you are redirected to the otherwise.
Hope this

How to deal with specific route state url parameters on AngularJS or Ionic? How to do route state override on specific parameters?

My question is simple, but I couldn't find solution anywhere else.
For example I have a normal route state with parameter,
.state('page', {
url: '/page/:pageid',
templateUrl: 'templates/pages.html',
controller: 'pagesCtrl'
})
However for example, if I have 1000 pages, but for the Number 1 and Number 999 pages I have to use another template. How could I simply do this? Something like
.state('page', {
url: '/page/:pageid',
templateUrl: 'templates/pages.html',
controller: 'pagesCtrl'
})
.state('page', {
url: '/page/1',
templateUrl: 'templates/page1.html',
controller: 'pagesCtrl'
})
.state('page', {
url: '/page/999',
templateUrl: 'templates/page999.html',
controller: 'pagesCtrl'
})
Will this work?I tested, the later 2 options are not overriding the original state with parameter.
If I wish to use the same controller, how to load the 1 and the 999 as the pageid parameter in the controller?
Definitely you shouldn't have two more state for separate template. You should use single generic state which will take templateUrl with the help of passed state parameter.
Code
.state('page', {
url: '/page/:id',
templateUrl: function($stateParams){
var template = $stateParams.id.indexOf([1, 1000]) > -1?'pages.html'
:'page'+$stateParams.id+'.html';
return 'templates/'+template ,
}
controller: 'pagesCtrl'
})

angularjs - ui-router - can we preload nested state?

I have this in my app.js:
$stateProvider
.state('actionplans', {
url: "/actionplans",
templateUrl: "pages/actionplans.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
})
How can I default load nest view action 'actionplans.summary.html' when called actionplans.html?
There is a working example
The way which will
load some view inside of a parent - and stay on parent
allow child change it when navigating to child
is called Multiple named views:
.state('actionplans', {
url: "/actionplans",
views: {
'': {
templateUrl: "pages/actionplans.html",
//controller : 'ActionplansCtrl'
},
'#actionplans': {
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
}
}
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
})
What we did above, is that we used views : {} object to define two views. First is targeting the index.html (the '') the second is targeting this state view target for children ( the '#actionplans').
views: {
'': { // index.html
...
},
'#actionplans': { // this targets the unnamed view for children
Read more about absolute names here
Another way, is to define some default redirection, but that will disable parent state as a real target (e.g. here Redirect a state to default substate with UI-Router in AngularJS)
Here discuss about AngularJS Routing Using UI-Router, you will get enough idea about nested view and multiple view.
https://scotch.io/tutorials/angular-routing-using-ui-router
I found a simple solution here.
$urlRouterProvider.when('/actionplans', '/actionplans/summary');//<-- Add in this line
$stateProvider
.state('actionplans', {
url: "/actionplans",
abstract: true,/// <-- Add in this line
templateUrl: "pages/actionplans.html",
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
})
This will load nest view actionplans.summary.html by default when you call /actionplans. My apology that I did not make this clearer in my question so I post the answer here hopefully it will help someone else with the similar scenario.

Angular ui router change state with query params

How i can go to a state and add query params to the url at the same time?
Lets say i have this state:
$stateProvider
.state('cart', {
templateUrl: 'client/cart/cart.html',
url: '/my-cart',
controller: 'CartController'
})
I want from some views to $state.go('cart') and from some views to $state.go('cart') but with query params added to it like, /cart?purchase=complete
So i found the answer, i hope it will help for someone else.
$stateProvider
.state('cart', {
templateUrl: 'client/cart/cart.html',
url: '/my-cart?purchase',
controller: 'CartController'
});
And then:
$state.go('cart', {'purchase': 'complete'});
The results will be:
my-cart?purchase=complete
try this
$state.go('cart', {'purchase': 'complete'});

Categories

Resources