Manually change state with ui-router in angular - javascript

I have a search bar in my app. Anytime a user makes a search, I'd like the state to change to /#/search/:query
To do so, I attach the following function to the scope and I trigger it anytime a query is made:
this.searchItem = function searchItem(item) {
$state.go('#/search/' + item)
}
However this results in the following error:
Error: Couldn't resolve '#/search/query' from state (current state) at object.transition.To
What is the problem with my code? How can I change state without using anchors with ui-router?
Many thanks

You're passing a URL when you need to pass the name of your state. See the ui-router wiki for examples.

Pass the name of the state instead of the url.
this.searchItem = function searchItem(item) {
$state.go('search', {
keyword: item
});
}
Assuming you have this state configuration in your routes.
$stateProvider.state('search', {
url: '/search/:keyword'
})
You can check my sample repo here: here and here

Related

How to use router.push for same path, different query parameter in Vue.js

Current url is
/?type=1
I want to use router.push on this page.
this.$router.push('/?type=2');
But this gives NavigationDuplicated error.
I don't want to use params like
/:type
Aliraza already answered your questions but I am sharing this answer because I see your comments asking, component don't rerender, for rerendering components you need to watch params like this:
watch: {
'$route.params': 'functionToRunWhenParamsChange',
}
That's because it's not different from your current path.
If the value of type is different it won't give you NavigationDuplicated error.
you can separate query like below too to make sure it will be understandable by the framework:
this.$router.push({
path: '/',
query: { type: 2 },
});
Please see this GitHub issue. They're using this.$router.replace but I imagine it shares the same root cause as when you are using this.$router.push. The proposed solution / workaround is to use an empty catch chained to the $router call, so:
this.$router.push('/?type=2').catch(err => {})
EDIT
You can pass the query params as an object to the second parameter of this.$router.push as well:
this.$router.push({ query: { type: 2 } })
<router-view :key="$route.fullPath"
If you wanna change your url (I mean push to another web page) and reload that page, you should use this syntax:
window.location.href = "your-url"
GG

Angular ui-router: load values for data and params from service

I want to load data and params for each state once when the app loads from my service settings (this service returns also promise since data are loaded asynchronously).
Something like this:
.state('tutorials', {
url: '/tutorials',
templateUrl: 'partials/tutorials.html',
controller: 'TutorialsCtrl',
data: {details: false}, // instead of false I want: settings.get('tutorials_data_details')
params: {popular: '512'} // instead of '512' I want: settings.get('tutorials_params_popular')
})
Those params must be loaded for all states before entering any state since they are used to build links with ui-sref directive that can be placed in any html pointing to any state (and those default params will be used).
Problem is that I cannot inject service into the config function. And using resolve will not handle all states at once.
I think $stateProvider.decorator could be used but I don't know how.
I would have commented, but not enough reputation for that.
If it's possible, one option is to create a parent abstract state such as app, so your state tree would become app.tutorials and then you can use resolve on the app state, allowing all sub-states to use the data/params.
something like this:
.state('app', {
url: '',
abstract: true,
templateUrl: 'partials/tutorials.html',
controller: 'AppCtrl',
resolve: { <resolve your dependencies here> }
})
.state('app.tutorials', {
url: '/tutorials',
templateUrl: 'partials/tutorials.html',
controller: 'TutorialsCtrl'
})
Note the Tutorials state wont load until the resolve is completed.
After some research and thinking I came up with these 3 possible solutions:
1) By using decorator we make all states resolving settings service.
.decorator('data', function(state, parent) {
state.resolve.SettingsLoaded = ['settings', function(settings) { return settings.$promise; }];
return parent(state);
})
Then in settings service use load success callback to setup states. You can use $state.get() to get all states (or with string parameter to get specific state by name) and modify the params object.
NOTE that you cannot use short version like state.params.popular = '512' but the full one: state.params.popular.value = '512'.
2) Those params could be actually functions that will be injected and invoked, and the result value will be used.
So the new params definition in the state will be:
params: {popular: ['settings', function(settings) { return settings.get('tutorials_params_popular') || '512'; }]}
Also I used again the same decorator to make sure settings will be resolved before any state is loaded.
I like this approach the most since all parameter values stays in settings service and the change is being dynamically reflected.
3) Since I'm using RequireJS, I could load settings using that and then inject it to the router file. This would however require more changes to the exising code in my settings service...

Stuck at Anglular ui-router State.go with hash url?

I am working on ui-router. I have a state:
.state('new-personal-orders', {
url: '/orders/new-personal-orders/:catId?',
template: '<new-personal-orders></new-personal-orders>'
})
In my controller i can make the state call with the
$state.go('new-personal-orders',null,{reload:true})
In the Html File i have an anchor tag:
Link
If the tag is clicked the state changes and 'new-personal-orders' turns into the current state with the trailing hash in the url. The url then looks like:
http://localhost:3000/orders/new-personal-orders#12
I want to do the same from the controller file with the $state.go() function of ui-router. But the hash url is not added.
My question is that is there any way that the hash url can be passed by the $state.go() in ui-router?
It seems that you can now put a hash in the state params like so:
$state.go('new-personal-orders', {'#': catId });
And you don't even need a /:catId in the state configuration at all.
See https://github.com/angular-ui/ui-router/pull/1867
You can pass state params as an argument in $state.go :
$state.go('new-personal-orders', {catId: 12}, {reload:true})
// refers to: http://localhost:3000/orders/new-personal-orders/#12
It seems that you are attempting to implement the same inside an ng-repeat, then you should replace 12 by something such as order.catId etc.

Child state with ui-router not resolved

I'm still working on an angular app, using the great ui-router. I'd like to use some dynamic nested states (I talked about it here), so I know it's possible.
Here is my code, with a specific state and its dynamic children states :
.state('home', {
url: '/home',
controller: 'RouteCtrl'
})
.state('home.state', {
url: '/home/:state',
controller: 'RouteCtrl'
})
$urlRouterProvider.otherwise('/home')
I have 3 buttons (more specifically, I use <a> to make it) to access 3 differents states : 'home', 'contact' and 'about'. 'contact' and 'about' are 'home' nested states and every state has a specific text to display when activated.
Unfortunatly, it appears that both of the children states aren't resolved from 'home' state.
Here is a plunker of the problem which match with my problem. Any idea ?
This will give you a working call to the new states:
$scope.redirect = function(state) {
console.log('redirect to state : ' + state);
if (state != 'home') {
$state.go('home.state', {
'state': state
});
} else {
$state.go('home');
}
}
However, it still won't change the text on the page, because the controller only sets it once when initially loaded.
Technically home, contact and about are not 3 states. What you appear to be doing is altering the content based of the parameters of the state. This could be achieved using one state and forcing ui-router to reload the state when you use $state.go
I have modified your plunkr here http://plnkr.co/edit/XXaltjG17FwY15tSbKaD?p=preview
Your state definition could look something like this,
.state('home', {
url: '/home?state',
controller: 'RouteCtrl'
})
The question mark makes the state parameter optional and also a query string.
The redirection could look something like this. You need to reload as you are going to the same route
$state.go('home', {state: state}, {reload: true});
Redirecting to the home page could look something like this. You need to disable inheritance for this redirect as you don't want to keep the query strings.
$state.go('home',{}, {reload: true, inherit: false});
The main problem here is that you want to have a variable in the state. You can't go to state home.about since it's not a given .state.
You should look at stateParams, or you can specify the URL where you want to go to the URL with Angular's $location.
Note: I think the url for a child state like home.state does not need the /home URL since it's in the father's state.

Getting part of a URL path via Angular.js

I want to get part of a path in URL via Angular.js and i found solution:
http://mywebsite.com/one/HEREiWANT/three
first i do this:
app.config(function($locationProvider){
$locationProvider.html5Mode(true);
});
then i define my controller like this:
app.controller("mainCtrl", function ($scope,$location) {
//...
}
then with this method i can get what i want and it works!:
$scope.getURLPart = function () {
return pId = $location.path().split("/")[3]||"Unknown";
};
But this has a huge problem, right now after this changes, all of my linkes in my website doesn't work. When i click on a link, address in browsers address bar changes but i stay at the same page and redirection process doesn't happen. Why? How i can achieve what i want without with this problem?
In your state if your using state and yor passing params to your state then you can use
$stateparams to get the params
$stae.go("particular state name") to route to states

Categories

Resources