SPA - When to use Location Based or Internal State? - reactjs

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.

Related

How should a React app (or any SPA) interact with a HATEOAS back-end?

The basic question is if there should be one HATEOAS entry point per page or one entry point for the entire app?
Most examples I have seen implement a single page with a HATEOAS backend, e.g. a list that is paginated using prev and next links. But what happens when the app navigates to a different page that has completely different capabilities and needs a different entry point? How does one organize such an app?
Concrete example: We have an app with tab navigation. The home tab shows a product catalog so the entry point is /products which returns page 1 of products along with pagination links. However, now I click on the orders tab which must show a list of past orders. This page needs a completely different entry point /orders which the home tab knows nothing about. In fact, user can directly navigate to the orders tab using a deep link.
How to think about this problem? Are there any examples illustrating an approach?
There's a few different ways to solve this. Here's two:
The SPA takes context from the uri (such as an id), and uses it to search on the API. The API can describe templated links/actions to search for resources by their id.
Instead of doing client-side routing, let the server decide what to render.
We're going more towards #2. If we have a uri such as:
https://spa.example/https://api.example/foo/bar
We take the path part of this uri and hit the API. Based on what the API responds with, we decide what to render. This means that most of the routing for these kinds of endpoints is delegated to the server, which feels more in line with HATEOAS.
The path part in this case is an entire absolute URI, but we also support relative uris and have a default base uri. So in practice these two uris are equivalent (for our SPA):
https://spa.example/https://api.example/foo/bar
https://spa.example/foo/bar
We develop & use ketting / react-ketting to do most of the heavy lifting

Is it done with Local-storage ? or data-binding in React JS?

I am new to react and developing the react application, where I want that user can save his/her selected values on the frontend and later on can also see those values via clicking a button and user can see what values have been selected previously. now the question is how to provide this functionality, I have studied that either it could be done by local-storage or by the data binding concept in react, but I have no clue which one is best to implement in my scenario.
Let me explain to you with the help of a diagram.
(The first Image with Indicator Generation)This is the main page of my React Application, under the section of "Question & Indicator" there is a thing called Associated Indicator, these are the values which user have select itself on the Frontend side.
(The second image with detailed user-controls) This is the page where all the user-controls are defined, here user can select the values and at the end when user clicked "Associate" it will be associated and the values have been shown under the section of Associated Indicators, from that user when clicking any of the associated indicators it will show all the values selected by user on front end.
Cheers.
Preserving data in a web app is not related to React -or any other front end technology specifically.
Data binding is a concept on how to update your views when certain data changes, and it is not related at all to how data should be saved. But related to how modern front end technologies like react and angular render your components.
You can save data in a web app using different methods, each one is suitable for certain use cases - and so you should use the one that suits you.
For example you can use any of the following:
Cookies: old way of saving data on the front end, can stay infinitely but can also be deleted if the user decided to delete them or clear data from his browser. Cookies Get send to the server-side with each request done with the browser, has limitations with size.
IndexedDB: This one is literally like a database inside the browser, really fast when querying data, also has bigger Size limitations than both Cookies, and LocalStorage. However, this is a really low level API. Won't recommend to use it, unless you really need its features. Can also stay infinitely, and can also be deleted by user.
LocalStorage: New browser API to persist data, much more easier to handle than Cookies And IndexedDB, Can stay infinitely, but can also be deleted by the user. Has bigger size limits than Cookies, but less than IndexedDb.
SessionStorage: Data saved for each tab, and data cleared when page session ends.
Finally If You want data that persist for forever and the user can't delete it, you have to do your own solution in the backend.

URL handling in a Hypermedia (HATEOAS) driven AngularJS application

We are looking for some advice on handling URLs (and the state related to each URL) in a web application backed by a HATEOAS REST API, more specifically on
how to avoid having the web application URLs coupled with the REST API URLs
how to handle multiple resources in a single view
But let me first provide some more context:
We are building an Angular web application on top of a REST layer with Hypermedia constraint. (Note: I prefer simply using the term 'Hypermedia (constraint)' over HATEOAS).
As dictated by the Hypermedia constraint, the available actions and links in the application at any point in time are provided by the REST API. So the web application should not contain any hardcoded urls of the REST API, except for the 'root' (assuming that concept really exists in a REST API).
On the other hand, each page in the web application needs to be bookmarkable. So we cannot create a black-box application (with a single url and all state changes handled in the SPA without changing the URL). This means the web application also has its URL space, which needs somehow to be mapped to the REST API URL space. Which is already a conflict with the Hypermedia idea.
In the Angular application we use UI Router for handling application state. Here is how we got it working:
We only define states, no URLS
We defined a $urlRouterProvider.otherwise handler that will map the current web application URL to the corrsponding REST API URL, retrieve the representation of the resource that corresponds with that REST URL and pass it to the controller (in $stateParams).
The controller can then use the data (and links and actions) in the representation, just like it would if it would have made the REST call itself (or through a service)
So far so good (or not really) because there are some downsides on this approach:
The Web application URLs are mapped to the REST API URLs, so both URL spaces are coupled, which conflicts with one of the basic assumptions of using Hypermedia constraint: we cannot change the REST API URLs without having to change the web application.
In the $urlRouterProvider.otherwise handler we retrieve the representation of the current web app URL. But in some cases we have two resources in a single view (using UI Router nested states): for example a list of items and a detail of a single item. But there is only a single URL, so only the representation of the item detail is retrieved and the list of items remains empty.
So we would love to hear some suggestions on how we could improve on our approach in handling the two URL spaces. Is there a better way to make the REST API dictate the (available) behaviour of the web application and still have bookmarkable URLs in the webapplication? Because now we have some kind of hybrid approach that does not feel completely right.
Thanks in advance.
Regards,
Luc
that's a tough setup. Roughly you want bookmarks into your API, and RESTful systems somewhat discourage bookmarks.
One possible solution is a "bookmark service" that returns bookmark (bit.ly like) urls for the current resource being presents that are guaranteed to be fowards compatible because as you may change the canonical url structure, the bookmark service can always translate the bit.ly like url into the canonical url. Sounds complicated, but we see this all the time and we call them SEO urls eg: /product-name/ maps to products/ today, but may be /catalog/old-products/ tomorrow.
How you match that up to a UI that shows 2 resources the first being a list of summary like resources, and the second being a specific resource get's really tricky. I would expect such a page to know contain the state of what's it's displaying in it's url (probably in the fragment). As such since it's [likely] the controller that processing such commands it probably needs both (the list resource and the expanded resource) as input. I bet the url would look something like:
list=http://path/to/list/results&expand=http://self/link/of/path
So the last part you have is to make sure that works going forwards. Again this is the bookmark problem. What i may suggest if you don't want to build a bookmark service is that given you want to have such bookmarks you need to transition people to the new URLs. When a request is made to http://path/to/list/results and you want to switch that over you should be 301 redirecting them to the new canonical url and the app should be updating the bookmark. such a redirect can include the &flag=deprecate_message param to trigger the presentation in the UI that the client's bookmark is old and should be replaced. Alternatively the response can be internally forwarded and the deprecation flag & canonical (or latest) link included in the response to the old URL. This causes a phased transition.
In summary: I have yet to see HATEOAS be a cure all for backwards & forwards compatibility, but it's much better than the existing techniques. that said you must still make decisions in v1 of your API about how you want your users to move to v2.

Backbone - how to maintain state in my case

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.

Building my own `like` system

I am thinking to build my own like system, as a way of learning various technologies including Javascript; and to gain a better understanding of authentication and XSS.
Use-case:
Unique ID generated atop a little bit of Javascript code, for embedding in any website
When unique user presses this like button, a +1 is triggered to the 'score' of that UID
On unique user's profile, display what they like'd
I'm unsure as where to start... how would I go about building this system?
Building such system is easy. Securing it properly, making it flow nice and be easy to integrate is the hardest part. You should ignore the latter 3 for now. I would start with a JS file that searches the DOM for any elements with the ID of "mylike" (for example) which inserts a button on to said page. Once a user clicks the button it simply does an AJAX post back to your server containing information like the page title and page URL. I think it may be best for your backend to generate the ID, maybe an algorithm based on the title + URL.
To include user data to know what user liked what I'd suggest a persistent cookie that has a session variable to link to a user in your back end. Simply pull the cookie out using JavaScript and send the cookie along with the AJAX request.

Resources