Browser history not maintained when using backbone history with hashchange - backbone.js

So for a Backbone/Flask app I have I am using Backbone.history to keep history of a certain page, and I am using parts of Flask to route through other parts of the app.
A standard user would flow through my application like this:
Load page /location; the /location page is served by flask and does not contain much javascript. It just displays some buttons.
The user clicks on one of the buttons and is redirected to /room/<id>/charts; again the application handles the routing to this page, and returns a html page containing the backbone application.
When this page is loaded I call Backbone.history.start() and I register some routes that should be handled by the backbone app on this page.
Now, when a user goes to several of these routes, and then clicks the back button of the browser, the browser will only go back until the first route that has been loaded by the backbone application on the /room/<id>/charts page. Even though I visited the /location page before coming to this /room/<id>/charts page that initiated the Backbone.history.
How can I make the Backbone.history work so it will work for the routes handled by the Backbone application, and also for the pages handled by the browser before the Backbone.history was started?

Related

What is the best approach to deal with page refresh in a Single Page Application?

I used to build websites using Java/Spring that there will be a controller to capture the request for a specific URL (e.g. mydomain.com/xyz) so that user can hit the refresh button in the browser and the page is still showing. But with Single Page Application since all pages are loaded all at once, what happens when a user hits the refresh button on one of the pages there? The browser will try to send a request to the backend but the backend knows nothing about the specific URL, what is the best way to deal with such situation?
In the simplest case, you have your web server configured to deliver the HTML of your web application at any URL.
For example:
http://example.com/
http://example.com/foo
http://example.com/foo/some/deeply/nested?link=true
Would all return the same HTML, which loads the same javascript which launches your application.
Then your single page app uses routing, where it looks at the current url and decides what component to display based on that.
React Router is a popular choice for this. You setup a series of paths that are rendered by components with something like:
<Route path="/books/:id" component={BookPage} />
<Route path="/users" component={UsersPage} />
<Route path="/safety" component={SafetyPage} />
When when your app starts up, and /books/123 is in the URL, then BookPage is rendered.
To take that further, you can have the server pre-render your components and deliver your page the way that your frontend application would have rendered it. You still have routing as above, but now the application "rehydrates" that HTML as the basis for your UI. This helps with loads times, since the entire code of your app doesn't need to load to see content, as well as allowing search engines to index your content (since they don't execute javascript).
This is a bit more complicated, but if you're curious, Next.JS is a popular choice.

if i used angular but handled routing through backend would it be still a single page application?

I read that if i handled routing through server, when a client asks for a page resulting the server to render a new document which will also result to refresh the web page unlike frontend/angular routing.
No. It wouldn't be a single page application. If you route through backend, whenever you change a route, your entire application will be bootstrapped in the browser again losing the essence of angularJS

Single Page App on React.js and ZF2. Is it possible?

I'm thinking how to implement a SPA on Zend framework 2 using Reactjs? Haven't seen any tutorial that might help me. So, I was asking if this is possible. How would zf2 will handle the routes?
The routes are handled on the client side (by pushing URLs into browser's history so you can also use browser's back button for navigation)
Simply put, changing a route will not load a whole page from the server.
The server does not even know that your JS app is changing the URL in the browser (imagine you write by hand http://example.com#test while you were already on example.com; that #test thing is a fragment URL and it will never be sent to a server)
Instead, the JS application will respond to (once again, client-side) route changes by rendering a different page or section, and making some ajax calls to the server to fetch or update data.
Now let's see what the server should do:
send the first page (the "single-page") and the assets (CSS, JS) on
the first load
respond to app-originated AJAX API calls once the page is loaded and
the JS app has been started
That's why they call them "single page apps", because they do much of the logic and the presentation in the browser (DOM rendering, routes), and the server merely acts as a data layer, or a backend if you like this word better.

catch server redirects in angular router

I am using angularjs routing. When I navigate to a view angular makes the request for the HTML defined in the templateUrl of the route. However, in a certain scenario - where the user's session has expired - the server returns a redirect. This redirect is followed and the resulting HTML is placed in the ng-view div.
This results in the login page being embedded within the original page which is no good. How can I make angular redirect the whole browser window to the redirect URL rather than just the contents of the ng-view?

Server-side redirect to angular SPA view

How do you get a server-side redirect to go to a certain view in an angular app? I am guessing it has something to do with the redirect not triggering the part after the hash, but can this limitation be beat?
More info
I'm redirecting from an MVC controller to a page with an angular app. I'm using ui-router. The page containing the ui-view gets rendered, but processing stops there. If I refresh twice or go to the URL manually the page works as expected.
The MVC controller is called from a form which posts a file to the server and asynchronously populates a database and redirects when it's finished.
I don't see the problem, you can send a full url with hash and all on the location header and the browser will follow it, just check the response headers for this:
http://web-cf8f140d-22d3-4acd-b7a5-f9fa4e15e094.runnablecodesnippets.com/
What you can't do is getting the hash part directly from the request on the server side.

Resources