Backbone - how to maintain state in my case - backbone.js

I've read a lot of threads here but can't find a real answer.
I'm building a desktop app that first loads a lot of json records (let's call them "cards"). Then the user can filter them down with by using many checkboxes, so he can "sum/substract" options (read: query vars).
I'm also trying to use routes.
So, I can have for example (and I don't really know if I'm doing it the right way):
app.com/#/cards/?near_address=London
app.com/#/cards/?near_address=London&cat=concerts
app.com/#/cards/?near_address=London&cat=concerts&day=8
app.com/#/cards/?near_address=London&radius=10000
[...]
Basically, every time the user change filters, I should add/remove query vars.
I could do it in many ways, for examble using some simple "state" json object, but I'm not sure it would be a good practice, mostly because I'm not really sure if I can instead do it maybe only by using routes (I'm quite new to the routes concept).
Is there any "good practice" in doing this kind of things with backbone?
thank you

Using routes to store state is actually a very good idea. That's what routes are there for, to store state, but it's up to you how granular you would want to go with them. some developers choose to go route per page and some choose to get more granular like your example and that's perfectly fine too. You just have to be careful not to go overboard and make your URLs too long and cryptic.
Using routes to store states gives your a few really important benefits:
Your pages will be refreshable. There is nothing more annoying than refreshing a page and losing all your progress and be take back to the start page of the app.
Your URIs are sharable. I could create a filter see the result and send the uri to anyone and they would see the same page as I was.
They make your life easier as a dev. which goes back to your pages being refreshable, they allow you to change your styles or scripts files and refresh the page and see the updated page without having to navigate through your app to get back to the same view over and over again.

Related

SPA - When to use Location Based or Internal State?

Hopefully this is not too opinionated but I am wondering if there are best practices regarding location-based SPAs and Internal based SPAs.
Internal based SPAs - track state internally
Location-based SPAs - URL location / Sessions , etc
In one part of my site if a user pastes in the url the search results will show.
However if I should be doing it for areas like admin section.
For instance I am allow users to add inventory to this point
admin -> add new Inventory -> choose center -> choose subcategory -> add inventory.
This is pretty much the flow, however if I would make it location based then on the "add inventory page" I would have to set the
company
center
subcategory
Which would require ajax requests to get all the data and basically every page I would have to do setting up data. It just seems like alot of work that every page has to be fully setup if they are coming from a url.
I am already using stuff like react-router to do my routing but in the end of the day I would to make sure that everything is always setup to the page can basically run standalone.
So maybe in some situations it would be better to somehow just redirect users back to the root of everything instead?
I would recommend using React Context for resolving your problem.
Once authorized, you can set the Provider value to be the user or their permissions, then on each ComponentDidMount or render() or whatever lifecycle hook you choose, you can check the users permissions and then allow the functionalities based on that.
Context values persist throughout routing, so you won't have to worry about updating it all the time (although you probably should if your user has a timed session).
So it is fully possible and probably more effective to use a mix of both internal and location based state management.

AngularJS - Shop list best practice

I'm new to AngularJS, and i'm want to know what's the best and easiest practices to do this simple shop list application.
So this is my shop:
I got three servers in my select input. Each server got own list of items, displayed in another component.
I'm thinking about creating routes with variables like localhost:4200/shop/{server1} which gonna show my list of items based on url path. Select option will just change path in my application to show shop list for specific server.
Is it a good practice, or there is better and easier solution to implement this simple shop application?
If you're asking if filtering data with routing is a good practice with Angular, I can say that it is not a bad one. Here's a link to the official Angular documentation about routing : Angular - Routing
But if you're asking if it is the only way to filter data or spread parameters, the answer is clearly no. Angular projects are SPA (Single Page Application), so you can do everything without touching the url.
For a quick example, you can attach a (click) event on your elements that display the shop list you want
I think you can use just one component and three different click events to display three different results. One component can work in your case. Using a router and routing logic for your requirement will be a costly affair. Your user will have a better application feel if these are covered in just one component and with three different click events.

Single Page App without URL

I'm joining a team that is currently working on a single page app. It is written with AngularJS, but it doesn't matter for the topic.
The App is so complex (many independant views with complex different states within each) that they completly removed the router (well, excerpt the default route).
I'm googling around but I can see no example of webapp that is not trying to work properly with URLs. Is there any risk of not using any URL, beyond the fact that "it is not the elegant way" ?
EDIT : ui-router does not fit, because of this issue : https://github.com/christopherthielen/ui-router-extras/issues/90
It sounds like you want to look into something like UI-Router which works on states.
https://github.com/angular-ui/ui-router
I can't imagine any significant issues with your app if you do it this way, but I can see massively bloated controllers and code to try and get around any issues you find.
as #Varedis said, you can use ui-router, but to answer your actual question, consider the use case for urls.
If you have only one url, there's only one entry point into your app. This can be annoying if the user expects to be able to quickly go to a certain area (state) within your app. Only one url means that the user can't bookmark, directly go to, or find with a search engine, any specific part of your application.
You can use other mechanisms like cookies or LocalStorage to keep track of state, but these are less user-visible.
I work on the project and i founded a month ago, ui-router-extras which provide parralel states but it can't instiante more than one state instance.
Is there another solution to do that ?

Maintaining application state across single page view flips and multi-page flips

Well, as technology progresses, issues we solved long ago crop up again.
Back in the dark ages, when PHP and ASP were considered awesome, we always had a problem with view states. If you had a page with say a dozen select combo boxes on it, your user chooses some combination and hits next, then realizes they screwed up and hit the back button on the browser, the combo boxes would be back in the default state, usually with option[0] selected. In order to prevent this, we had to write boatloads of boilerplate code that would save the state of those combo boxes to a cookie, or session variable, or something so that when the user hits the back button, we can reload the combo boxes back to the state they were in when they left.
This problem was compounded even further if you had a datagrid on the screen. Because then you would have to come up with some slick way of saving that grid somewhere to prevent from having to hit the database again.
Then came the light. Browser developers realized that most web developers were on the verge of going back to writing terminal programs in Cobol due to this issue and added UI caching to the browsers. This allowed us webdevs to not have to worry about this anymore except in odd situations.
So, life was good. Then someone came up with the bright idea of trying to replicate GWT without all the hassle and the web explodes with all these javascript frameworks. The one im dealing with specifically at the moment is AngularJS 1.2.10 with Angular-UI. I have until Friday (most likely wednesday tho) to make an initial assessment on if this technology is a viable alternative to our current standard (thats pretty much universally hated) JSF.
So, i follow some guides, pound my head against the desk a few times, and I have an angular app with 3 actual HTML pages, each HTML page with 2 views.
Before you go there, understand we can't use it unless we can do multi-page JS apps. Some of the applications that this will be worked into have been in development for a decade or more and its simply not financially practical to scrap an the entire UI and start over again. We would instead be doing things like taking these 50 struts pages and converting them to angular/rest and linking them seamlessly back into the remaining 800 struts pages of the application.
So in my exercise of playing with this, I encounter my old nemesis. Back button view state issues.
I have been playing with the UI-route system. The fact that I can deep link using the route system solves part of my problems. But, if say I have a search page like this:
view-search
combo: search type [member,nonmember]
combo: result type [detail,summary]
combo: search state {all the states]
textbox: contract number
etc etc etc
And various combinations of combo box selections and text entries comes up with a list of 1000 people. Now the user selects one of those people on the data grid and it takes you to view-detail. Well the fact that you can use routing to do something like index.html#detail/bob is cool, but if the user realizes thats the wrong bob and hits the back button, they get a blank search screen again and they have to enter everything over and worse yet, send another search to the database to rebuild the datagrid. Some of these screens have 50 or more options to choose from when searching for data so trying to put all of them into the URL routing sounds completely impractical to me.
Now in my research I found this post:
Preserve state with Angular UI-Router
And that has promise mainly because I have a view state object that I can store into a Redis database or a session EJB for cases when the user actually jumps out of angular and into the legacy Struts application, then back buttons back into the angular application, but the fact still remains that on some of these pages, that is a huge amount of boilerplate code that we would have to write in order to make it work.
I don't really mind the idea of having to manually save off the view state object and read it back in from a Redis server or something anytime a user enters or leaves an HTML page in the system. What i'm really looking for is a way to automatically generate the object that is to be saved without having to write volumes of boiler code.
Is this possible? I keep reading the ui-route documentation but it doesn't look like this is addressed, at least not that i've translated yet.
If this is possible, what controls should I be looking at?
thanks
-------------- Edit
I just thought of something. There is one central scope to each of the single page applications. (Im basically going to be building a multiple single page apps and hooking them together) So if i use a naming convention, something like this
$scope.viewstate.view-search.searchType
$scope.viewstate.view-search.resultType
$scope.viewstate.view-search.searchState
Then the viewstate object should simply be a js array and when I create a function to move to struts.do, i can simply save that array off to the Redis server as a nested map object. Then when my user back buttons back into the angular app, i can capture that using the route system and retrieve that viewstate object from Redis and insert it back into my scope, thereby rebuilding the scope for the entire single page app in one shot.
Would that work?
I believe that you have a very complicated issue of trying to keep the view states between your varying pages with the amount of data in your pages. I think that the only real effective way to do this is to write an angular service that you can then pass to your various pages. as You already know the service is a singleton that you can use in various controllers and could be utilized to maintain the view state as you described. here take a look that this link and see if it will help: http://txt.fliglio.com/2013/05/angularjs-state-management-with-ui-router/
After some thought what you suggest in your edit might work, but I would still use a service to retrieve that array of data, as it would make it easier to reinsert in to angular scope
I am exploring something similar for an Angular app that I am writing. Keeping a user login during a page refresh is easy. Displaying the state on the page after a refresh is an entirely different problem.
How long must the state be persisted? I'm evaluating two possibilities.
First, saving the state (current form values or whatever) to the database. As the page changes, incrementally save the state to the database. On a browser refresh check the database for saved values.
Second is to use local browser storage. This is 5 megs of storage. 5 megs is a lot of text. Again this data would incrementally be saved into storage. When the browser refreshed, simply load data from localStorage.

Efficiently handling backbone pushState routes server-side?

I have Backbone working with pushState. It's very nice, but now I understand that I should support loading the app from any route that backbone uses. For example, if somebody enters a backboen route manually to their browser, the server should respond to that and render the page and then let backbone take over.
What I am wondering, is what is the most efficient way to handle it? Backbone recommends also bootstrapping data on initial page load to reduce ajax requests. Should I only try to bootstrap data that is necessary for that particular view or should I try to bootstrap basic collections (for example: users, settings, documents, etc)?
For the first part of your question, you could just specify a callback route (which matches everything and gives the homepage) so the user never gets a 404 (don't use that when developing the app though, it could give you some hard times debugging it if you have a real 404 when making a call to the server).
For the second one, I'd say it depends on the amounts of data you need. I'm personally developing a modular application, and unfortunately can't really bootstrap anything. I'd say it's just some advice.

Resources