AngularJs - Persistence, storage, ajax requests, data integrity - ajax

I'm evaluating whether AngularJS will work as a solution for my moderately simple web application.
The aim is to cut down the amount of AJAX server requests for data as much as possible.
My actual question is simple, yet the repercussions of that request is leading to confusion.
In a nutshell: "Can Angular modify parts of JSON data received from a backend through user input and maintain state until I'm ready to return that data.
Scenario:
Grab JSON data from the server that contains a root name & associated address details for each root name. The list is rendered to screen along with an 'Edit Address' button for each item.
The user clicks 'Edit Address', Angular displays a form with the address data for the root name.
The user edits the data, clicks submit, the client sends JSON data to the server and, for arguments sake, we get a success return. The address details are modified.
This is where the meat of my question - and lack of understanding - comes to the fore.
Do I need to get the entire list of 10 items back from the server with the single modified address details, just from editing a single list item OR can I simply update that single item client side and hold state as the user returns to the list, say, to edit another item?
IOW, we get a success, but no data is actually returned aside from 'success' - our client has stored the changes.
This is where the data integrity issue rears it's ugly head.
** OR **
Grab a list of root items without associated address data.
The user clicks on an 'Edit Address' button for the root item.
We fetch the address data for the root name from the server and the form is displayed, the user edits the data, submits, send data asynchronously, get a success.
User returns to the list and another server request is made to grab the list from the server again.
This is hellishly difficult to explain, but the bottom line is about persistence and data integrity.
Is it best practice to make a server requests after each user edit of data, or can modified data be stored client side - with persistence?
obviously validation will be done server side, as well as client side.

What you're asking is more of a server-side question, on how to design a good RESTful API that allows changes to individual entities without sending/loading the entire list each time. So the answer to your question is that it's entirely up to you... angular does a great job of binding UI elements to the javascript objects in your controllers for you, but when it comes time to save that data to the server, you can do it however you want.
In an ideal world (IMO) your server-side API would support the following:
Get a list of addresses (angular stores them in $scope.addresses)
Get a single address
PUT/PATCH to update an address (when a user makes a change to a single address and confirms it) and return 204 no content
POST to create new addresses, and return the created address with a server-provided identifier (like "id"), that you can use in angular to determine whether an address has been persisted server-side or not. After POSTing, you rewrite the angular scope object with what you got from the server to save the id field.
DELETE to remove them (returning nothing)
With this, when you have the client create an address, you should send a POST to the server to create one, take the response JSON and copy it over the object you just saved, so that now it has an "id" field (or similar). You can use angular templates to visually represent that anything with an "id" field is saved to the server. This way you don't have to re-grab the whole list every time you save.
For updating addresses, this is why PATCH is useful: you can send only the changes to individual fields to the server and ensure that only things the user has changed get sent.
Deleting addresses can work by checking if the "id" field is there, and if so, send a DELETE to the server, and if not, the object was never "saved", so just remove the address from the scope. Upon successful deletion you can just remove the address from the scope, no need to reload everything.
When it comes to the "data integrity", ie. if there's other addresses created since you've done the original data request, you'll have to do this on your own... Ideally similarly to how Stack Overflow or Github does it, which is to hint in the UI that there has been server-side changes and you should click to refresh. How to determine refreshes is up to you, but you can keep it simple with polling at intervals, or you can go all out and do WebSockets/Server-side events and actually push changes to the browser.
The best way to create UIs that persist to the server is a complicated topic and there are a lot of best practices. Angular will support whatever you want, but you need coordination on the server to do it.

Related

crudGetList action does not delete from state data not present in response

WARNING: This question is specific to react-admin framework
I'm trying to do an in app manual, that uses data from server to load content pages. To doing so I'm doing a custom page that fetches manual pages on componentDidMount. In this function I call react-admin crudGetList(resourceName, pagination, sortingById, filters), where filters is {and:[{condition},{language: currentLanguage}]} since I want to have the manual in different languages. I noticed that having pages in different languages in database and using crudGetList action with filters fetches the correct instances, however the state maintains old data. For example if I initially fetch data in English language, change language and go back to manual page, redux state will have pages for both languages instead of the current selected one.
Is this expected behaviour? Making the new request for manual pages shouldn't replace redux-state data to data coming from request? If is not expected should I open an issue?
React-admin uses a pattern called optimistic rendering. That means that if the app has fetched some entities in the past, if it needs to display these entities, it first shows the stale entities, then fetches the backend, and if the response differs, re-render the screen with up to date data.
For instance, when a user fetches a list of posts, react-admin stores these posts in a dictionary indexed by id:
{
123: { id: 123, title: "hello" },
456: { id: 456, title: "world" },
...
}
React-admin also stores the list of identifiers that the list should display:
[123, 456, ...]
Using these two properties, react-admin can now display the list. But it can also display the detail of a post without hitting the server first. So when a user clicks on an item in the list, react-admin uses the data from the first structure to display it right away, without waiting for the server response.
The purpose of optimistic rendering is performance: since the user doesn't need to wait for a round trip with the server, the interface is super snappy.
In your particular case, I understand that this can cause problems, because the store contains stale data that is not in the desired language. I suggest that you create a custom saga, which reacts to the language change action, and clears the store to avoid this kind of problem.
Check the documentation for custom sagas in the react-admin site:
https://marmelab.com/react-admin/Admin.html#customsagas
You have to configure how the redux store responds to new incoming data.
More specifically, this is what a "reducer" is for; your "action" (in your case crudGetList) feeds the data into the "reducer", which is just a function with instructions to the store on how it should adjust its shape based on the new data.
Somewhere in your app there's probably a reducer that responds to your fetch action, but it's configured to just shove the new results alongside the old, rather than replace them. It's very difficult to know, however, without seeing the code describing the entire redux "cycle".
The redux docs are excellent. I'd start there and make sure you have a good understanding if the entire flow of data through redux, and then go hunting for that reducer.
https://redux.js.org/basics/reducers

How to implement form that requires users to validate email or phone number?

I'm trying to improve this form to make it a little more user friendly.
The main area I'm trying to improve is the validation process.
Right now, the form gets filled out on index page /, and the user is re-directed by the server to a /validate page. To improve the experience, the email or phone number is shown to the user so they can see whether they entered it correctly. (though rarely, it does happen)
I'm also not sure if the user should be given the opportunity to use another form of validation.
The one problem with the setup on the server side is storing the form information between page requests.
Currently I'm using the flash(one-time sessions) to store the email or the phone number. Once the user submits the form the session is lost.
I don't like using sessions for forms, because any time you have more than one window open (not that they should be in this case) the data can start to become unpredictable
I also don't want to use the url params for storing information, as this can have sensitive information being passed back and forth, and stored in browser history.
I was thinking I could do ajax, which I try not to use on sites facing a broad audience where someone is bound to be using an old version of IE.
The data I get from the form is stored in the database. I could use the GET method to store an id in params. If I use the id (or a random unique id) I run the risk of anyone guessing these ids and having access to other website users' email address and phone numbers.
I could also use a combination of the flash and hidden inputs with the unique id, but the danger of showing personal information is still there.

Tracking ajax request status in a Flux application

We're refactoring a large Backbone application to use Flux to help solve some tight coupling and event / data flow issues. However, we haven't yet figured out how to handle cases where we need to know the status of a specific ajax request
When a controller component requests some data from a flux store, and that data has not yet been loaded, we trigger an ajax request to fetch the data. We dispatch one action when the request is initiated, and another on success or failure.
This is sufficient to load the correct data, and update the stores once the data has been loaded. But, we have some cases where we need to know whether a certain ajax request is pending or completed - sometimes just to display a spinner in one or more views, or sometimes to block other actions until the data is loaded.
Are there any patterns that people are using for this sort of behavior in flux/react apps? here are a few approaches I've considered:
Have a 'request status' store that knows whether there is a pending, completed, or failed request of any type. This works well for simple cases like 'is there a pending request for workout data', but becomes complicated if we want to get more granular 'is there a pending request for workout id 123'
Have all of the stores track whether the relevant data requests are pending or not, and return that status data as part of the store api - i.e. WorkoutStore.getWorkout would return something like { status: 'pending', data: {} }. The problem with this approach is that it seems like this sort of state shouldn't be mixed in with the domain data as it's really a separate concern. Also, now every consumer of the workout store api needs to handle this 'response with status' instead of just the relevant domain data
Ignore request status - either the data is there and the controller/view act on it, or the data isn't there and the controller/view don't act on it. Simpler, but probably not sufficient for our purposes
The solutions to this problem vary quite a bit based on the needs of the application, and I can't say that I know of a one-size-fits-all solution.
Often, #3 is fine, and your React components simply decide whether to show a spinner based on whether a prop is null.
When you need better tracking of requests, you may need this tracking at the level of the request itself, or you might instead need this at the level of the data that is being updated. These are two different needs that require similar, but slightly different approaches. Both solutions use a client-side id to track the request, like you have described in #1.
If the component that calls the action creator needs to know the state of the request, you create a requestID and hang on to that in this.state. Later, the component will examine a collection of requests passed down through props to see if the requestID is present as a key. If so, it can read the request status there, and clear the state. A RequestStore sounds like a fine place to store and manage that state.
However, if you need to know the status of the request at the level of a particular record, one way to manage this is to have your records in the store hold on to both a clientID and a more canonical (server-side) id. This way you can create the clientID as part of an optimistic update, and when the response comes back from the server, you can clear the clientID.
Another solution that we've been using on a few projects at Facebook is to create an action queue as an adjunct to the store. The action queue is a second storage area. All of your getters draw from both the store itself and the data in the action queue. So your optimistic updates don't actually update the store until the response comes back from the server.

Reason to discourage use of back or refresh button on net banking sites

I just want to know why refresh/back button is not recommended while using netbanking sites?
Is it because of session object that might get invalidated?
Your average banking site contains forms. To protect the user from accidentially performing some action by eg. clicking a link (or, more general, by some sort of request forgery), the forms can have an additional hidden field containing some random value.
That random value is also stored on the server side and used to check whether the form can contain parameters for a valid action (ie. the form token must match the server token).
The disadvantage is that, if you use the browser controls, you get back to the previous page, but probably without the server noticing. Thus, you use an old form token, the result being that the server will refuse to perform the specified action, because the form token does not match the server-side information.
As a side effect, this incident may lead to the currently active session to be terminated for security reasons.

Best practice for combining requests with possible different return types

Background
I'm working on a web application utilizing AJAX to fetch content/data and what have you - nothing out of the ordinary.
On the server-side certain events can happen that the client-side JavaScript framework needs to be notified about and vice versa. These events are not always related to the users immediate actions. It is not an option to wait for the next page refresh to include them in the document or to stick them in some hidden fields because the user might never submit a form.
Right now it is design in such a way that events to and from the server are riding a long with the users requests. For instance if the user clicks a 'view details' link this would fire a request to the server to fetch some HTML or JSON with details about the clicked item. Along with this request or rather the response, a server-side (invoked) event will return with the content.
Question/issue 1:
I'm unsure how to control the queue of events going to the server. They can ride along with user invoked events, but what if these does not occur, the events will get lost. I imagine having a timer setup up to send these events to the server in the case the user does not perform some action. What do you think?
Question/issue 2:
With regards to the responds, some being requested as HTML some as JSON it is a bit tricky as I would have to somehow wrap al this data for allow for both formalized (and unrelated) events and perhaps HTML content, depending on the request, to return to the client. Any suggestions? anything I should be away about, for instance returning HTML content wrapped in a JSON bundle?
Update:
Do you know of any framework that uses an approach like this, that I can look at for inspiration (that is a framework that wraps events/requests in a package along with data)?
I am tackling a similar problem to yours at the moment. On your first question, I was thinking of implementing some sort of timer on the client side that makes an asycnhronous call for the content on expiry.
On your second question, I normaly just return JSON representing the data I need, and then present it by manipulating the Document model. I prefer to keep things consistent.
As for best practices, I cant say for sure that what I am doing is or complies to any best practice, but it works for our present requirement.
You might want to also consider the performance impact of having multiple clients making asynchrounous calls to your web server at regular intervals.

Resources