I have a search page, where the user can perform a search and see a result.
Initially, my issue was to update the router URL without navigating, but I solved that by using "Location".
My ngOnInit - my search page can be navigated to by another page, so I listen for queryParams to perform the search if any happens:
ngOnInit() {
this.queryParamsSubscription = this.activatedRoute.queryParams.subscribe(queryParams => {
this.searchText = queryParams[TD_QUERY_PARAMS.text];
if (this.searchText) {
this.search();
}
});
}
my search method:
search() {
const queryParams: Params = { text: this.searchText };
const desiredUrl = this.router.createUrlTree([], {
queryParams: queryParams,
relativeTo: this.activatedRoute,
skipLocationChange: true
});
this.location.replaceState(desiredUrl.toString());
}
This implementation makes sure that I update the URL when the user searches within the search page, which was the first part of my solution.
However, I also want to add any search to the browser history, ie:
I start by launching my application on 'localhost:4200/landing'.
On this page, I have a search bar, that when triggered will navigate to my search page.
From the landing page, I search for '1'. The router then navigates to: 'localhost:4200/search?text=1'
Then on the search page, I search for '2'. the search is performed, and the URL is updated to: 'localhost:4200/search?text=2'
Finally I search for '3': ''localhost:4200/search?text=3'.
When I then press the browsers 'Back' button, I would expect to be navigated to ''localhost:4200/search?text=2'.
However, none of the searches I made within the page has been added to history, so I will be navigated to whatever page I was accessing before the search page. In my case, 'localhost:4200/landing'.
How can I add each of these searches to the browsers history?
I believe that one of these is what yo need:
this.router.navigate(['/yourRouteGoesHere'], { replaceUrl: true });
The other options that you have is to use: SkipLocationChange this.router.navigateByUrl(['yourFullPath'], { skipLocationChange: true });
use this.router.replaceUrl('path').
That way you can navigate, without adding this route to history.
This was a case of way overthinking the issue I was facing.
By just using router.navigate(['/search'], { queryParams: queryPrams })
I got the result I desired. The URL was changed, a point was added to browser history.
What I failed to realize, was that router.navigate, will not reload the entire page, when only the queryParams are changed.
Hope this helps anyone struggling with the same issue.
Related
I'm building a search bar for my app with vue-bootstrap-typeahead autocomplete lib, if your not familiar with it, when you click a suggested result it triggers the #hit event, passing the result data to the method.
<vue-bootstrap-typeahead
...
#hit="goToResult"
...
/>
Then I have the goToResult method
methods: {
goToResult(result) {
this.$router.push({name: 'market', params: {marketId: result.id}});
},
...
}
When I do search from a non-market route it works fine, redirecting the user to the desired /market/:marketId route, but when it's done from a "market" route it just changes the URL but doesn't redirects to the new market, it even triggers the "duplicated route" error if I click the same result twice, but still not redirecting.
Any suggestion?
Thanks
Check out the note at the bottom of the router.push section: https://router.vuejs.org/guide/essentials/navigation.html
Note: If the destination is the same as the current route and only params are changing (e.g. going from one profile to another /users/1 -> /users/2), you will have to use beforeRouteUpdate to react to changes (e.g. fetching the user information).
...and here is how to use beforeRouteUpdate:
https://router.vuejs.org/guide/essentials/dynamic-matching.html#reacting-to-params-changes
Hope this helps!
If the user removes the param from the url manually. I want to add back the value of the param in the url using Angular 6. Let's say,
https://localhost:4200/root/param1/product
Here user is removing param1 from the url,
so, now the url will be like this,
https://localhost:4200/root//product
and it is redirecting to login page. But I don't want that redirection.
I am using resolve here.
resolve(route: ActivatedRouteSnapshot) {
const param1 = route.paramMap.get('opportunity');
if (param1 === null) {
this.cart.createOpportunityId().subscribe((opp) => {
this.router.navigate(['/root', opp, route.url[3].path]);
});
}
}
Here I have written a condition to find whether the param is null.
But when i tried to remove the param1 manually. The page is redirecting.
I am facing this issue when the param value is null and when it is wrong param value, url is working fine.
Please help me out to find if user manually removes the param from the url, how to find it is null and how to add back real value.
Well, like you said if you remove param then page redirects, then the reason must be you have defined such routes in your routing module.
Like:
{path: '/root/:anotherParam', redirectTo: '/login', pathMatch: 'full'}
{path: '/root/:opportunity/:anotherParam', Component: ComponentB}
When second route fails to match as there is no param opportunity, first route matches, then it redirects you to login route.
Like you said if you provide wrong param value, it works because it matches with the second route(having wrong opportunity).
For redirecting purpose you should reconsider your routes.
You can also use localstorage or sessionStroage(will be best) to store the user param and then check the param in the routes, if there is no such param, then you can get it from local/sessionStorage.
Hope it helps you.
Using Angular Router, I want to navigate to another url without adding it to the browser history.
this.router.navigateByUrl(`${pathWithoutFragment}#${newFragment}`);
Can I do it with only Angular?
Thanks to NavigationExtras you can now use replaceUrl: boolean inside navigate()
This will replace the current url, and the new URL will update in the address bar:
this.router.navigate([`/somewhere`], { replaceUrl: true });
That way when you press back it will not remember the previous page in the history.
As #IngoBürk Mentioned in the comment you can achieve the same result without using skiplocationChange
this.router.replaceUrl('path')
skipLocationChange
Navigates without pushing a new state into history.
this.router.navigateByUrl([`${pathWithoutFragment}#${newFragment}`], { skipLocationChange: true });
Ref:https://angular.io/api/router/NavigationExtras#skipLocationChange
Any ember-way ideas to make a manual transition to a wildcard route with a dynamic segment at the end */:category_name, so I can manually build a "breadcrumbish url version" example, suppose a user enters to /banana I need to transition the user to /Groceries/Healthy/Fruit/Banana.... groceries, healthy, fruit might be entered as well so /Fruit would be transitioned to /Groceries/Healthy/Fruit... I was able to make it work using window.history.replaceState on the model hook of the route but strange enough it only works if it's being refreshed or type in by user, not while transitioning in template, thanks in advance guys
Route as is
this.route('products', function(){
this.route('wildcard_handler', {path: '*/:category_name'});
this.route('handler', {path: '/:category_name'})
});
Recap of cases:
Case 1:
User enters /products/banana
-Redirect to /products/groceries/healthy/fruit/banana
User enters /products/fruit
-Redirect to /products/groceries/healthy/fruit
Case 2:
User enters /products/groceries
-All good, it's correct.
Case 3
User enters /products/groceries/snacks
-doesn't exists so, 404 redirects.
All of this trouble is only for making a better UX for a new ecommerce I'm building, the normal suggested way is to just use one dynamic segment
Like
this.route('products', function(){
this.route('handler', {path: '/:category_name'})
});
It's fair, but it's way nicer to build the breadcrumbish url
Again, thanks in advance
Case 1:
If you want to redirect the user to another route before resolving the model, you can use beforeModel() hook. You can also use redirect() hook to redirect the user to another route. For example (when user visits /products/fruit, you can redirect them to products/groceries/healthy/fruit in redirect hook),
redirect(model, transition) {
this._super(...arguments);
this.transitionTo('products.groceries.healthy.fruit');
}
Refer this link to know about the predefined hooks in routes.
Case 3:
Refer this link to know about wildcarding routes in your application.
In my ember app, when the user clicks the Back button of browser,I need to stop the transition (whereever it might take me as per Ember history) and reload the same url with same model. Have tried the below code, but doesnt seem to work:
search-route.js
var route = Ember.route.extend({
actions:{
willTransition: function(transition){
if(this.controller.get('order') === 1){
transition.abort();
this.transitionTo('search',model)
}
}
}
})
This doesnt seem to work and gives error about query params. So, i looked for what is there in transition object. Saw that as soon as I enter this code, the object transition contains prop queryParams but with the old values, not the current URL one. But there is another prop - transition.intent.preTransitionState.fullQueryParams which contains the current URL query params. Would that be used here somehow.
I looked for solutions and someone also suggested to put in this.refresh(), but also didn't work.
I'm trying on my own ember app and doing a transition.abort() followed with a this.refresh() works.