In my Angular 8 project, I currently have a landing page (template-table.component) that shows a list of items that can be filtered and sorted. The filter and sort are added to the route queryParams(ex: "/template-table?name=another&type=Type%201"). If you select an item in the list, you will be taken to another route (that has the template-details.component) that has more details on that item. This details page will have a 'back to list' button that should take the user back to their previous list page.
Since I want the user to be taken back to the list with the filter params they were previously using, I can't simply go to the route of that component, instead I want to go back in history (like how the browser back button works). So, how do I set an element to link to what the browser back button would be link to?
So, this is the bare minimum of my template-detail.component.html:
<h1>template-details works!</h1>
<div>{{template}}</div>
<div>{{id}}</div>
<div><a routerLink="/template-table/">Return to list page</a></div>
I think I also would like to check the route to see if it's the template-table component route with query params, and not an unrelated route. (So, the route would need to be like: "/template-table?params=xxx", and couldn't be "google.com". If the browser back button isn't related to the template-table, then it should go to "/template-table" without any params (or maybe my 404 page.)
The basic functionality that I'm wanting to achieve is for the user to be able to filter a list, go to another route with more info on a list item, and then return to the list with the same filters they previously added. If there would be a better way to do this than by trying to access the browser's back button, I'd love to hear about it.
Thank you for any assistance you can provide.
Arthurofos' suggestion to use the Location service seems to be relevant, as it can be used to navigate back to the view you were in prior to routing to a new component.
Of course, while there are very Javacsripty-ways to do these sort of things, it's always recommended to use Angular's libraries, if such an alternative exists.
In our case, it does, and it presents itself as the 'Location' service you can inject into your component.
import { Location } from '#angular/common';
#Component({
// Other component info
providers: [Location, {provide: LocationStrategy, useClass: PathLocationStrategy}]
})
export class TestComponent {
constructor(private location: Location, // Other constructor arguments) { }
public goBack() {
this.location.back()
}
}
https://alligator.io/angular/location-service/
Something like that should work:
routerLink="../"
But you can solve this problem in an elegant way thanks to the location of the library. Check out this post: enter link description here
Related
I am trying to implement "go back" functionality for a page that could be access from n different urls.
Example, all the following URLs will link to abc.com/b1:
abc.com/a1
abc.com/a2
abc.com/a3
abc.com/a4
...
abc.com/an
From abc.com/b1 I want to support a link that takes you back to the previous page you visited.
My first attempt is to use:
...
const navigate = useNavigate();
navigate(-1);
...
However, if you land straight in abc.com/b1 navigate(-1) will likely take you outside of my application into some other site, or browser about:blank.
What is the best approach to implement such functionality?
is there a way to access the history length to check wether we should navigate(-1) or push a new page?
should I pass additional state/query from a pages to b? so b knows how to go back? this seems like overkill.
Thanks.
I was with the same problem, but I finally found a solution that worked for me.
I'm using the react-router-dom#6.2.1.
// Simply return to the previous page or to the initial route
navigate('..')
I'm implementing a small project with only two UIs.
1-The first UI is called Home which contains paginated users list the home component.
2-The second UI is called user details which contains user profile the user-details component
3- and of course the app component which contains the tool bar and router-outlet
let us suppose the following scenario
I'm in the home UI and in the second page of the paginated users list and I clicked on one of the users item then the user-details UI appeard and I'm now in the second UI and I now I want to navigate back to the home but when doing so the home UI is recreated and become the first page of the users list instead of the second page where we left it because this is my code of the back button
<img
routerLink = "/home" style="cursor: pointer;"
width="40"
alt="Angular Logo"
/>
<span routerLink = "/home" style="cursor: pointer;">Users</span>
my question is:
is there is any way to implement it in such a way it doesn't recreate the home page i.e. implement the correct behavior of back button?
There's a couple ways that you can approach this.
If you're using a pagination library (such as ngx-pagination), then hopefully the pagination component takes an input for the current page. You'd then need to keep track of that page either through a service or in persistent storage.
Whenever you route back to the Home UI, get the page that you were on and load that back into the pagination component.
Another way can be to use router parameters. By modifying your urls a bit, they can take on the following form:
/home/1
/home/2
/home/3
Clicking on a user in page 2 can give the url: /home/2/user-id (just an example)
The path for your home component can look like:
const routes: Routes = [
{ path: "home/:pageNumber", component: HomeComponent }
];
Upon loading the home component, you can get the get the router parameter as follows (I'm using the Router method but you can parse the URL manually as well):
export class HomeComponent implements OnInit {
constructor(private router: Router) {
const pageNumber = this.router.navigationExtras.params['pageNumber'];
}
}
You can then load this page number into your pagination component. Using this method doesn't require you to keep track of the previous pages.
There are probably better methods to do this, but this is just some suggestions :)
Currently I have a sample which I'm working on which is a basic master details page. This sample uses react-router-redux. Within the details panel I have a number of tabs which use can see different facets of the selected item... all fairly standard stuff.
When the user selects an item from the master list, the URL that the clicked <Link ... /> send them to is something like customer/123. Within the route that is registered for that url (i.e. :id), I have an indexRoute route which replacess the route to default route/tab /customer/${nextState.params.id}/address.
All this works well and the user can navigate between tabs just fine. The problem comes when the user closes the detail window and selects a different detail. As expected, it opens the tab based on the route specified by the indexRoute. Under normal circumstances, this might be fine but I want it to remember which route was selected. I'm wondering if anyone has ideas on how this should be done?
I think I can do achieve this by registering a callback with the onClick event of the Link and dispatching an event which will result in key of the selected tab being saved in the store. Then within the onEnter of the indexRoute I can access the store and pull out this saved state and target the replace to this that item.
This should work but seems like a lot, just wondering if this seems right to other?
I would use the same approach - dispatch an action when the tab is clicked and store the tab key in the store.
Use mapStateToProps to retrieve the value.
I have a new product page with the url /product/0. When product is saved using a button, I want to show 'Saved Successfully' message and change url to /product/1024 without actually navigating to that page as this would cause GET requests for the product and other data on the page.
I tried the Navigation mixin, however both, the transitionTo and replaceWith actually cause componentWillReceiveProps and I can't figure out a way how to distinguish my case (when all data on the page is already relevant) from navigation between different products, when data has to be reloaded.
So basically I am looking for a way to just change the url with React Router.
In a SPA there's no navigating to another page, the history change could lead to a different route being rendered, but as per your example, the same route will be rendered, so the only thing that did happen is a state change of the props of the Route component.
So you need to check this state with the previous state in componentWillReceiveProps and see if you need to refetch the data.
I'm creating an image gallery that loads a specific image if it is specified in the route (else loads the first):
foo/photos/sports/2
Each thumbnail is wrapped in a link to cause the address to change (so users can link back to it directly):
<ul class="gallery-thumbnails">
<li ng-repeat="piece in gallery.pieces">
<a ng-href="/foo/photos/sports/{{$index+1}}">
<img ng-src="{{piece.img}}" />
</a>
</li>
</ul>
The problem is that it causes the whole view to be re-rendered instead of just the template binded to the changed scope param (scope.gallery.selected).
I can't find a way to cancel the view re-render (but I still want $routeParams to be updated).
I've seen solutions that listen for $locationChangeSuccess, but that doesn't work for my scenario.
One way to get close is to use get parameters instead, going to /foo/photos/sports?page={{$index+1}} and in that route (as an argument to "when") set reloadOnSearch: false. You can then update the $location.search (the get parameters) without the page reloading and trigger things on the changes.
// Using reloadOnSearch
.when('/foo/photos/sports', {
templateUrl: 'sports',
reloadOnSearch: false
});
// Changing the get parameters (search part of url)
$location.search({'page': 1});
Apart from that I don't think you can do it with the default angular router. It always reloads all controllers on a routechange. You could however switch to another router such as ui-router which I believe can handle reloading parts of a view on path-change.