How to do background sync instead of fetch requests on UI changes? - javascript

For example, let's take a simple web application with comments feature. In my understanding, when a user posts a new comment, the following would occur:
display UI loader;
update the front-end state;
send a fetch request to the API to post a new comment;
Wait for the response;
send another fetch request to the API to request the new list of comments;
waiting;
update the front-end state with new comments;
update UI to reflect the new state with a new comment;
And the user needs to wait while front-end app interacts with back-end on almost every data change. The same way we did it earlier with PHP/Python/Ruby, ajax, server-side rendering and templates.
That makes me think what's the point of adding so much front-end complexity with something like react, when the result is basically the same.
My question is: are there any alternative approaches to this? Is it possible instead to do the above case the following way:
user clicks to post a comment;
update the front-end state;
update UI to reflect the new state with a new comment;
sync front-end state with API DB in the background;

Well, as your question is tagged react, you could use the Apollo library (it is intended to work together with graphql on the backend) for data fetching. It offers a feature called Optimistic UI, which will be update the frontend with the respected result, until it receives an answer from the backend. If the expected result differs from the received one, the component will change the UI automatically to the real result. In case of an error, it will show an error message.

You definitely could, your first method is just way of doing it.
Apart from 'syncing' your front-end state, another method is also to just pre-emptively update the UI (step 7 & 8 in your first method) before doing step 3-6, and only reverse the action if the API call failed. This should allow for slightly better UX for the end-user too.

I get it that you think it's waste of time for users to wait until requests are successful. However, isn't it more important to stop users from keeping making bad requests to the server?
So, what I would do is just to stop fetching data from the database every after users make requests.
Fetching the DB data to begin with and store them in redux states
Make requests to the DB while holding users from doing anything
Make changes to the redux state if the requests are successful
But what you want to do could be done like this
Fetching the DB data to begin with and store them in redux states
Make changes to the redux state while making requests to the DB in the background
Depending on whether the requests fail or not, roll back the change users made from the redux state

Related

Managing & Updating State with Redux-Persist & fetch new data in Background?

I have a component that makes an API request, gets some data. Then the data is put into a child component that puts it into redux:
Pseudocode:
let data = await apiRequestHere(); //some graphql query, using graphql-request
return (
<div>
<MyReduxComponent data={data} /> //inside here, data is processed and put into redux state
</div>
);
While the API request runs, I am showing a spinner.
Redux-Persist
Just implemented redux-persist. However, the way everything is set up right now is that the API request is made in any case, and the spinner is shown every time, so even with redux-persist it will wait for the data to come back from the server, making using redux-persist pointless.
How I would implement redux-persist properly and make sure that if there is data in redux-persist, use that data, make an API request in the background, and if there are any changes, then update. Don't want to block my whole app every time.
Did I go wrong in my setup here?

Node JS + Express JS: refresh page from other location

I have the following problem: I want to change one variable on a page. The input comes from another page so:
I'm using Node.js, Express.js and Ejs for this task.
Server - storing the values
Index page - Control page with input fields and send button
Display page - Shows the variable
I'm sending the variable with fetch post to the server. On the server I change the variable with the request body value and when I reload the "Display page" manually I see the new value. The problem is: I need to change it without any manual refresh or other things, because that won't be possible.
There is the possibility with "location.reload()" to refresh it every X second. But that's not the way I want to use, I really just want to refresh it when the variable changes. Is there a function (from express.js for example) I can use for it?
edit: I should mention that this project would be just used in our network and its not open for other users. Like an in-house company dashboard kind of.
So a "quick and dirty" solution can work too, but I want to learn something and wanted to do it the right way though.
This is a very common scenario that has several solutions:
Polling - The display page runs ajax calls in a loop every N seconds asking the server for the lastest version of the variable. This is simple to implement, is very common, and perfectly acceptable. However, it is a little outdated, and there are more modern and efficient methods. I suggest you try this first, and move on to others only as needed.
WebSockets - WebSockets maintain a connection between the client and server. This allows the server to send messages to the client application if/when needed. These are a little more complex to setup than just plain ajax calls, but if you have a lot of messages getting sent back and forth they are much more efficient.
WebRTC - This is taking it to another level, and is certainly overkill for your use case. WebRTC allows direct messaging between clients. It is more complicated to configure than WebSockets and is primarily intended for streaming audio or video between clients. It can however send simple text messages as well. Technically, if you want to persist the message on the server, then this is not suitable at all, but it's worth a mention to give a complete picture of what's available.
The simplest solution that came to mind is to have the server return the updated post in the body, then use that to update the page.
You can also read about long/short polling and Websockets.
One possible solution would be to add page reload code after a successful post-operation with fetch.
fetch(url, {
method: 'post',
body: body
}).then(function(response) {
return response.json();
}).then((data) => {
// refresh page here
window.location.replace(url);
});
Proper solution (WebSockets):
Add WebSocket server as a part of your Node.JS app
Implement subscriptions for the WebSocket, implement function 'state changed'.
subscribe on a method 'state changed' from your client browser app.
call ws server from your express app to update the clients when your variable is changed
Outdated (Polling):
Add express endpoint route: 'variable-state' Call server from your
client every n ms and check whether variable state is changed.
Refresh the page if variable is changed.

Extra GET API call after update call

As the frontend application has its own state, now the user updated his/her contact and the frontend state got updated and PUT API is called to update with the current state.
So while updating the user contact details through PUT call, should another GET call be made to fetch the user details or should the current state is enough for the frontend.
Just curious what is the advised pattern to follow.
Your PUTrequest should send a 200 ok so you know that the data frontside is now valid.
You could of course (this is what I do in some instances), is send the object back as a response of your PUT request with a 200 ok. With this object you can update your view as needed, ensuring that the object is exactly the same as the one on the server side.
A GET is not needed in this case.
Another get request is not necessary, If you really want to maintain the state from backend (which is also not necessary), you can respond from the server to the PUT Request with the state. This may come in handy if to know execution is successful.
After update(PUT call) you should make GET call to get the details from DB and display in the front end.
So that the user will get to know that the details are successfully updated.
OR
if you want to show update success message then in the backend you can return the updated values in PUT API call response and you can use this response to show details without making GET API call again.
OR else
Based on PUT call success response you can show the details that you set in the state without making a GET call
Not required.However,in the PUT request itself you can send the changed state.And you can concatenate/update the frontend state with the db state using filter method.In order to keep your frontend state intact with the db.

Is it a bad practice to re-GET list data after a successful item DELETE?

If my client-side application displays a list of items requested from my API, and a user deletes an item, is it best practice to then again call the list GET at the end of the successful HTTP DELETE promise and update the view? Or should the application state simply be updated locally after the delete, without hitting the API again?
I understand optimistically updating your application, but, that is more for view update performance rather than reducing server calls.
You should make another GET request to update the list if the list data may change without user interaction, eg: server-side updates, or another session that can change the same list
With the performance aspect, let the user see the entry deleted ASAP, then very shortly after they will see the updated changes (if there are any), and it won't disturb them.
If there is a deletion error, refresh the updated list regardless
EDIT: I'd also suggest using websockets

Server-side Changes to Model not Reflected in UI - EmberJS

I'm persisting my model from my controller via a call to this.get('model').save(). This results in a PUT to an endpoint that just returns a 200 message and nothing further. On the server side however, some custom rules are in place that are changing the data so that it's different than what Ember sent to the server. This puts my UI and my persistence tier into an inconsistent state.
What's the correct way to make sure the UI reflects what the correct state of the data after it was persisted to the server? Should my server-side endpoint return the updated model? I've tried just calling this.get('model').reload() after the save() but the UI isn't updating. When I did this I could see that it's asking and getting the new model from the server but as I said, it's not reflected in the UI.
I feel like there's some knowledge fundamental to Ember that I'm missing. Thanks for the help.
I guess that you are not waiting for the record to complete the updating process.
http://emberjs.com/api/data/classes/DS.Model.html#method_reload
So this would be:
this.get('model').reload().then(function() {
console.log("Now I am ready !");
})
Always remember that javascript is async.

Categories

Resources