We are using React-Admin v4, and some of our APIs are quite slow. We're using the search input field, and our problem is that api requests can overlap. If there is an existing fetch in progress, typing again doesn't cancel the existing fetch. It fires another one, and the results list is updated when each request returns, leading to confusing UI.
Can we configure the search field to cancel existing fetches when a new one is triggered?
React-admin doesn't implement Query Cancellation, although its underlying data fetching library, react-query, does allow it (see https://react-query-v3.tanstack.com/guides/query-cancellation for details).
So if you want to implement query cancellation in a react-admin filter, you'll have to build your own component based on react-query's useQuery hook, and populate a ListContext with the results. Check the Building a List View By Hand tutorial for guidance.
Related
We have a custom filter functionality which involves adding filters in bulk and applying them at the end. For this, every time a user clicks a breadcrumb, a search call will be performed to update the current list of facets but without updating the product list on PLP. The PLP will be updated only when the user clicks ‘apply’.
The search call needed to update the facet list is done at the moment trough a http call to the search endpoint but is there a better way to do this to benefit more of spartacus (in terms of caching for example)?
Should all the layers of the backend communication be extended for this?
The current spartacus version is 3.3
I made this autocomplete field that can be filtered by another dropdown field.
On initial load the autocomplete field loads a bunch of data through graphQl.
The problem is the data on initial load is huge and takes a while for this to finish.
On the meantime users can opt to filter this autocomplete list and thus making another request . The filtered request finishes faster and the data from the initial request overwrites the filtered results.
I am already using debounce for this one.
Is there a possible way to cancel the a request done through apollo-client?
thanks
As I know that, instead of get() I can use onSapshot() for my queries and listen to the changes(additions, deletions, modifications) for that query. But when there are changes, onSnaphot() returns multiple full documents whether modified, deleted or added (a new snapshot). What I want to do is, to check if new documents have been added matching my query and show a notification to the user that there are new records available, and only when a button is clicked, they should be able to fetch and see the new records. I don't want to fetch from the firestore whole sets of documents when there are changes. I just want to know about those changes and fetch on demand. And fetch only the added ones.
How can I do that? Any ideas?
By the way, I am using react-native for my app.
P.S. - I know, I can run the query periodically and check if the id of the first item in the new query matches the first item id in the previous query, and so I can detect the added records and show my notification/button. But I am looking for a more elegant solution. I think the notification should be triggered from the backend instead of polling the backend periodically.
P.S. 2 - Using cloud functions would not seem to be a logical option since these queries will be different for each user of my app. Which would require running thousands of functions (hopefully more) on the firestore. Or would it?
Thanks!
There is no way in the Firestore API to get notified about changes to a query without actually retrieving the changed documents. But you can of course show just a notification to the user when your onSnapshot callback gets called, and then only show the actual data from those documents when the user chooses to refresh the UI.
On a second note, when you use a snapshot listener the Firestore client will only retrieve the modified documents on additional callbacks.
Say you attach a listener for a query that matches 10 documents. On the first onSnapshot callback, you will get 10 documents and will be charged for 10 document reads. Now say that one of the documents changes. When your onSnapshot callback gets invoked for this, you will see 10 documents again, but will be charged only 1 read - for the document that was changed.
If you only want to process the changes, have a look at the documentation on viewing changes between snapshots, which contains a good example of how to do this with the docChanges() method.
I have an app and its going to have these features in it :
SCREENS :
Home { Show recent posts from all categories (API provides 30 posts per page)}
Categories {Show all Categories List }
By-Category {Show recent posts by category (API provides 30 posts per page)}
Post {Show Post Details with Comments }
User-Profile {Show User Profile with their recent posts (API provides 30 posts per page)}
Profile-Setting {Show updatable Fields and Update Button}
Now, Where i am confused :
Should I fill the whole store with API in the starting or should I
make API calls for each screen when they are opened ?
And for updating, like If user likes post then should I show a
spinner or something till API completes OR should I update the local
store value instantly and then call the API ?
There could be many approaches to solve this. mine is:
1) I would create a model/manager to handle the API requests that also have access to the same store. so for example when the screen did mount use Home.Manager.getNextPage(); and it will know already to handle the api request and also know how to handle the paging.
So all the calcs will be in the manager. and when it get the data it will update the store with it.
2) When I built an app that contained likes I have used local data as well. My approach was to set time out of 10 seconds from last like so in case the user liked more than one post I could send a bulk. so the server won't need to handle multiple tcp connection but one with multiple likes data.
The point was first store it locally(for incase the user kill the app before we update the server) and then wait for 10 s' if got new like add it to the data array and wait for another 10 s' if not just send the data to the server. do not clean this local data until server return that it saved on your db
This way you can display animation first without letting the user to wait for a feedback from the server..
The best practice is to make small API calls for each component.
You should load each screen with a loading, then call the API in
componentDidMount after receiving the response shows the data.
enter code here
For this kind of action, first, make the API call, make the like button disable, update the store after successful API call.
Disable the button because of some user double-tap. This kink of APIs is usually fast, so loading does not have a good UX. The loading will be removed before full animation. Always update store data on the response, not the request because you need to revert the store changes if the API calls failed.
Let's say I have this blog app. There are posts, pages, menu, and user login.
One way to load the entire application state is to have one api call which will include posts, total number of pages for pagination, menu items and current user state.
The second way would be to have multiple API called, one for each component. So one call for posts and pages, one for menu and one for current user.
Which would be best strategy given the fact react is built around components?
I'll add my 2 cents as answer but still wanting to close as primarily opinion based.
The way I structure my React apps is to have a top level components called Screens or URLs, ie., /list-users should map against the ListUsersScreen component.
In said screen I declare a static method called fetchData, this method returns an object which values are Promises.
{
users: fetchUsersAction(),
someOtherApiData: fetchSomeOtherAPIData()
}
This lends well to both pure client apps and universal apps, as well.
On your server side you'd have to wait until all Promises resolves until you can render something.
Furthermore you can easily cache the values in your application state object and decide if you want to fetch new data or render stale data, also it saves on bandwidth for your user since the user might or might not decide to continue browsing your site.