7

I am using query system which allows user to construct query from list of dynamic fields and I want to persist query in URL.

Normally I would do:

$stateProvider.state('alerts', {
                url: '/alerts/list?p1&p2&p3'
            })

and in controller I could read params with $stateParam:

console.log($stateParams.p1)

I could save query in URL by:

$state.go($state.current, {p1:'1', p2: '2'}, {location: true, inherit:true, notify:false})

But the problem is I cannot declare all params.

I would like to do:

$state.go($state.current, {p1:'1', p2: '2', p3:'3', p4: '4', p5:'5'}, {location: true, inherit:true, notify:false})

but ui-router ignores params that are no declared for state.

I know $location.search gives me access to URL search part but how can I set URL (without changing state and reloading page)?

3 Answers 3

3

This worked for me:

$stateProvider.state("alerts", { url: "/alerts/list?{query:json}" });

and

$state.go($state.current, {query: {a:1, b:2, c: '3'}}, {location: true, inherit:true, notify:false})
Sign up to request clarification or add additional context in comments.

1 Comment

This works on the page it's used, but when you try to navigate you can intermittently encounter a known issue called the "reload state bug" (as discussed on some of ui-router's GitHub issues pages) in which some of the parameters you've set in this $state.go are applied to the next state you visit, or the controller unnecessarily reloads, or other issues.
3

Make sure you are using the latest 1.x ui-router - this is important. Then in your route, use the dynamic: true in the parameter settings. This will prevent refreshing. Use the ui-sref as you normally would - don't use any of that notify/reload/location stuff at all as it will break things - dynamic takes care of setting those properly in the background. With value you can set a default one, and squash removes the trailing slash in the URL if it's empty (set to '' - not null).

.state('myappstate.somestate', {
        url: '/:a/:b/:c/:d',
        params: {
            a: {dynamic: true, value: 'someDefault'},
            b: {dynamic: true, value: 'anotherDefault'},
            c: {dynamic: true, value: '', squash: true},
            d: {dynamic: true, value: '', squash: true}
        }
    })

2 Comments

Thanks for the updated answer, but the question is how do we now differentiate between route changes caused by using $state.go (dynamic params) and somebody just going back by using the browser back button?
Wow, was facing a similar issue and it was the location: 'replace' that was breaking everything! Dynamic variables do take care of all of this. Thanks!
2

There is a very long discussion going back to 2013 on one of angular-ui's Github issue pages. So far no answer given has satisfied everyone, and I'm one of the unsatisfied people.

So far the best workaround is to use query parameters only (not url path parameters) and add the reloadOnSearch: true option to states you plan to use dynamic query parameters on (changing them without reloading the page). That's discussed in a different StackOverflow answer here.

As of the day I'm writing this, there is a branch of angular-ui with something called "dynamic parameters" which is now 300 commits behind master but might have solved the problem (but now it's far enough behind master that I don't want to use it). There is also an upcoming 1.0 version of ui-router but I do not know when that will be released.

1 Comment

I don't recall finding a solution to this problem. I also switched to another framework about a year after writing this question, so I'm no longer investigating it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.