React router 4 - routing questions on architecture using hashes - javascript

My Setup
I am using react router 4 in my application and am trying to achieve something along the lines of adding hashes to certain routes on pages, that will save the state of the page so user can link to said state.
So for example - I have products I am listing that have many variants, when the user selects a variant, I add a hash + the variant ID to the URL, so like myapp.com/cars/truck turns to myapp.com/cars/truck#red, this allows users to link to that specific variant, which is what I want.
My problem
My problem arises when the user navigates to a page and selects a few variants, then tries to navigate backward. Because I change the hash, each back step hits the previous variant in the browsers history.
So if
the user lands on home myapp.com/
navigates to myapp.com/cars/truck
then selects the red variant => myapp.com/cars/truck#red,
then blue myapp.com/cars/truck#red => myapp.com/cars/truck#blue
When they press the back button on the browser they will go back to myapp.com/cars/truck#red, when the desired effect is they go back to the previous page omitting the variant and hash changes, which would be myapp.com/.
I understand this is the browsers behavior, but what I am wondering is if there is a way to let users link directly to the variant links, and also have it so pressing the back button after the described scenario takes the user back to the previous page (in that scenario it's myapp.com/). Perhaps re-thinking how I am doing this, I am open to any suggestions.
I am using react (16) and react router (v4) for this if this helps. Happy to show any code if needed, please let me know. Thanks for reading!

Try replaceState, it will update the URL without adding a history entry:
history.replaceState() operates exactly like history.pushState()
except that replaceState() modifies the current history entry instead
of creating a new one. Note that this doesn't prevent the creation of
a new entry in the global browser history.
e.g.
history.replaceState(null, 'Red Truck', '/truck#red')

Related

react router 5 browser back button changing state

In my application, I have a multi-page form that lives on the URL http://localhost:3000/form. When I change pages in the form, the URL remains the same, but the state changes to render different views (pages of the form).
A new feature I want to implement is to allow the browser back button to switch views/pages (aka change state) in the multi-page form.
Is this possible? How can I achieve this?
Why exactly do you want to keep the same route? If a user wants to get back to the same state they were at via a deep link they would not be able to with this implementation would they?
If you want to use the same route you can at least use # routes to keep track of where in the form the user is.
Eg.
http://localhost:3000/form#step1,
http://localhost:3000/form#step2
then the back button would work to move them back a step.

Remove multiple items from history through JS

I have the following flow:
HOME => DEVICES => ADD NEW => SELECT TYPE => PAIR
Users can of course go back at any time. Now after pairing is complete I go to the DEVICES index page again.
When a user presses the back button on that page, it returns to PAIR (which I don't want), I want it to go to HOME.
I've looked at ReplaceState on the final step which changes the PAIR page by the HOME page before redirecting to DEVICES. That way when the user presses back in the DEVICES page he/she comes back at the home page (great!), however when the user then presses BACK again he arrives at SELECT TYPE which I don't want.
How can I accomplish that when the PAIR is done, the ADD NEW, SELECT TYPE and PAIR page are removed from history?
Side note: I'm using Turbolinks and Rails, although I believe the answer would be JS.
AFAIK, you cannot delete from browser history. But you can prevent saving history by location.replace (see https://stackoverflow.com/a/21820194/4486609) or do another mad thing like turning off back button at all, but...
if you have classic web app (not SPA) then you have some system to prevent user jump to abitrary step at your wizard, and if you have it, it is already solves such problem, isn't it?

Add history item to html browser history without changing page angular

I'm attempting to rewrite a small part of user history as soon as they visit my angular application.
Currently I'm attempting to change the last history item to a certain page once the app loads, however instead of just changing the history, the current page/url also changes.
In my app.js where I define my routes for angular I also have a .run containing
history.pushState({}, 'Restaurants List', document.URL.match(/.+#\//).toString() + 'orders/restaurants')
this instantly will change my url from the intended target to the new history entry.
I've also tried using replaceState without any success.
A solution I've thought of is first changing the history then redirecting the user which works fine, but I want to avoid that additional overhead.
Is there any way to just add to the history without going to it so that if the user hits back it goes to a different page?

How to handle pagination in Single Page Application?

On my Single Page Application (Javascript (AngularJs) webapp), I'm displaying a paginated items list.
I'm displaying 10 items per page.
In order to retain the current pagination opened by the user at any time while this one navigates on other page, I put the current page number on browser's localStorage.
Here's an example of workflow:
The user goes to myItemsList.html.
He opens the page 2 involving the url: myItemsList.html?page=2.
Then, he goes to another page: myOtherPage.html.
He goes back to the link initially pointing to myItemsList.html, that displays directly thanks to localStorage the page myItemsList.html?page=2 in order to potentially continue his navigation.
Would it confuse the user, maybe expecting to see the page 1 as a new starting navigation.
If I display at the top of the list, a kind of label like "Page 2" in order to warn him that he's seeing the preceding portion of his navigation, isn't it UX-friendly?
Or should I completely avoid persisting current pagination?
Here's what could happen if I don't persist the current viewed page:
The user goes to myItemsList.html.
He opens the page 2 involving the url: myItemsList.html?page=2
He opens an item in this page (the "show" page), leading to: myItemsList.html?id=123
He clicks on the browser's back button, causing a refresh of myItemsList.html (since a Single Page Application). The current pagination (page 2) would be lost and the user would need to restart it in order to continue its items discovery.
This seems really touchy...
What strategy should I choose for a use case like this?
saving the progress through navigation is the expected behavior in UX design of SPA, so maintaining the page he was in the correct choice, and since it is a pagination it won't be an issue even if the user wants to go back to any page, it will only take a click.
First of all I would avoid using localstorage and use a service instead to persist ur page counter.
Secondly u dont need to persist pg counter to anywhere else but in a scope variable for refreshing to mext page data. You can even think about just adding to results similar to infinitite scroll use cases. But either way, u can use local scope variable for pagination.
Whether to go directly to last viewed page - is a more business decision and will depend on needs.
But u can very easily persist or remove persisted data using broadcast and watch and decide on persistence based on event listened to.
Hope thos helps ...
How about maitaining a sort of heirerachy in JS like this :
Suppose a user navigates to a section called Customer Search
customer_search.customer_display.page = 2
Where customer_search is the a subsection , customer_display is the view with pagination you are targetting .
menu.menu_items.page=7
Where menu is the subsection , menu_items is the view with pagination
Might work if your application is organized in a reasonably hierarchical manner .
Probably you could also maintain the page in $scope for that particular controller .
The URL should dictate the navigation.
When I navigate to your website, e.g. example.com, I expect to be on the first page.
When I navigate to a (bookmarked) page of your website, e.g. example.com?page=2, I expect to be on the second page.
When I hit the back button, I expect to be presented with the previous page exactly as it was when I left it. You don't need to refresh the entire page, just listen to the history events and update accordingly.
And I strongly believe that this question doesn't belong to stackoverflow...

Issue with hash url in javascript?

I am using url hash to scroll the page. What i am doing is, say i have 2 pages :
Page1 and Page2
First i navigate from page1 to page2 and set the url hash than my url will become :
http://localhost:48785/page2#id
I am setting hash using this code:
window.location.hash = "id";
Than i press browser back button and went to previous page i.e. page1. Upto this point everythings work fine.
The Issue occure when i set hash twice on page2. Like:
http://localhost:48785/page2#id
http://localhost:48785/page2#id2
Now when i press browser back button, it just navigate back and forth between hash #id and #id2.
Why the back button not taking me to the previous page i.e. page1 after setting hash twice on page2 ?
That's the way the browser back button is supposed to work. It goes back to the last url change in the browsers history.
it looks like you can use history API like it described here http://www.thecssninja.com/javascript/stealing-history-api
enter link description hereyou can History API and try and remove the history from the browser so that you can get out of the loop
Because HTML5 : 6.6.9 : Navigating to a fragment identifier says:
When a user agent is supposed to navigate to a fragment identifier, then the user agent must run the following steps:
Remove all the entries in the browsing context's session history after the current entry. If the current entry is the last entry in the session history, then no entries are removed.
This doesn't necessarily have to affect the user agent's user interface.
Remove any tasks queued by the history traversal task source that are associated with any Document objects in the top-level browsing context's document family.
Append a new entry at the end of the History object representing the new resource and its Document object and related state. Its URL must be set to the address to which the user agent was navigating. The title must be left unset.
Traverse the history to the new entry, with the asynchronous events flag set. This will scroll to the fragment identifier given in what is now the document's address.
This is done so that links within a document can be backed out of in the same way that links between documents can. User confusion might result if hitting the back button only served as an undo for some link navigation and not others, especially when scrolling can cause a complete change in the content displayed.

Categories

Resources