problem is when GET_LIST request taking time, and we change the path like to go to show or edit page
in admin-on-rest we had cancelPrevious but now I'm not sure if we have it in react-admin anymore
this is reproducible when you have difference between what we loading in GET_LIST request in compare with GET_ONE
for example for GET_LIST you have
[{ id, createdAt}, {...}]
and for GET_ONE you have whole data like
{id, createdAt, deletedAt, content, ...rest}
expected behavior is when GET_ONE is triggered it should cancel GET_LIST
That's not how react-admin works. React-admin expects that both GET_LIST and GET_ONE return the same kind of entities, and stores these entities in the same place. React-admin uses the entities from GET_LIST to optimistically render the details of an entity, and the entity from GET_ONE to optimistically render the list of an entity.
If you want to serve different fields in GET_ONE, then you should write your own List component to render the list in a pessimistic way, i.e. wait for the server to return the up to date entities to show them.
I do not recommend it however. End users prefer waiting a long time once instead of waiting several times. So in general, they don't mind waiting a little longer for the list if they can get to the details faster. So I recommend that you include the same fields in the GET_LIST response as in the GET_ONE response.
Related
VueJS + Quasar + Pinia + Axios
Single page application
I have an entity called user with 4 endpoints associated:
GET /users
POST /user
PUT /user/{id}
DELETE /user/{id}
When I load my page I call the GET and I save the response slice of users inside a store (userStore)
Post and Put returns the created/updated user in the body of the response
Is it a good practice to manually update the slice of users in the store after calling one of these endpoints, or is better to call the GET immediatly after ?
If you own the API or can be sure about the behavior of what PUT/POST methods return, you can use local state manipulation. Those endpoints should return the same value as what the GET endpoint returns inside. Otherwise, you might end up with incomplete or wrong data on the local state.
By mutating the state locally without making an extra GET request, the user can immediately see the change in the browser. It will also be kinder to your server and the user's data usage.
However, if creating the resource(user, in this case) was a really common operation accessible by lots of users, then calling the GET endpoint to return a slice would be better since it would have more chance to include the new ones that are created by other users. But, in that case, listening to real-time events(i.e. using WebSockets) would be even better to ensure everyone gets accurate and new data in real-time.
I am new to vue-router and I am facing this problem.
Here is my code;
filter() {
this.$router.push({
query: {
bathrooms: this.selectedBathroom,
beds: this.selectedBed,
minPrice: this.selectedMinPrice,
maxPrice: this.selectedMaxPrice,
minLandSize: this.selectedMinLandSize,
maxLandSize: this.selectedMaxLandSize,
minLotSize: this.selectedMinLotSize,
maxLotSize: this.selectedMaxLotSize,
minYear: this.selectedMinYear,
maxYear: this.selectedMaxYear,
},
})
}
when user clicks on the filter button, the filter method is run. But the data doesn't update and when the user goes back to the previous page, the the query params is removed, but the data isn't updated.
Is they a way I can work around with this?
There is no path or name value here to actually initiate a change to the page route. If you want to simply reload the existing page with a new set of query parameters see this information from the documentation:
Note: If the destination is the same as the current route and only params are changing (e.g. going from one profile to another /users/1 -> /users/2), you will have to use beforeRouteUpdate to react to changes (e.g. fetching the user information).
In your comments you mentioned that you are making a request to a server. It's hard to give a full answer without more code from your application but query parameters might not be the most straightforward way to approach your problem. You should explore setting up a fetch request in your method or using axios to interact with the server (assuming you're communicating via an API) to build a more reliable and better scaling communication pattern.
I'm using Vue.js and vuex to work with data from a backend store that I access via and api.
My question may be more about semantics and how to actually ask this question and search for better answers because I don't even know the correct terms to be searching on. So here goes...
Within my vue code I make a call to my back end api and it returns a json blob with a block of data that i want to work with in the ui. No problems there. But then I need to slightly modify that data to present it to the user. this entails assessing a few fields and changing them (say, if the value is 0 put in 'n/a', etc.), maybe doing some math on a few fields and so on. Then I present that to the user in a grid/table. I want the user to be able to sort and search on the fields as well. So I may display a field named fullName that comes from the back end but allow the user to sort on a field named lastName that is not actually in the grid.
With that said, here is my question - should I be creating a single 'transformer/reducer' in code to translate the data object coming from the api into what I need for the ui? Or should I be writing multiple filters (by this I mean Vue.js filters that go directly in the html with the '|' pipe) to just modify the fields directly in the html template?
My concern is the once i modify the object coming back from the api what if I have to post/patch/put back some kind of update - then I need a 'reverse' transformer to get back to an object that my api wants to see.
Generically, I suppose my question could be boiled down to "how do I locally handle an api response object so that I can maintain its 'purity'?"
Or something along those lines. I'm obviously fumbling for the correct terms and that is why i'm struggling to even google for info on this topic. For that I apologize and any help would be appreciated.
Also, I realize there is nothing Vue-specific about my question as this issue could apply to any data-driven ui framework.
I think I get what you're asking now. You just want to know if you need to modify the response before making it consumable by the UI. Let's say you're using axios. What I would do in Vue is use the response.data object as the data to inject into the vue data property. For example, your response.data returns an array of objects. You would hardcode a data variable in Vue like this:
data () {
return {
apiData: []
}
}
and with the API response, set the data array like this:
const response = await axios.get(...);
this.apiData = response.data.filter(item => return item.foo === bar);
Now apiData holds a filtered version of the response data, which was asynchronously retrieved for processing, including the ObjectId's for each object. Note: I would call this during created(){} hook to allow time for the GET request to process prior to DOM mounting.You can reference the array objects by the ObjectID within the UI, like this:
<div v-for="item in apiData" :key='item_id' :item="item">
<p> {{item.whateverProperty}} </p>
</div>
Let's suppose I have a collection of books retrieved by a Vuex action called fetchBooks (this action commit the SETBOOKS mutation to change state).
When I dispatch the action remove to remove a book, I have two options:
1) Send request to the API to delete the resource and then dispatch fetchBooks to reload the books listing.
2) Send request to the API to delete the resource and then commit the REMOVE mutation to remove the book from state, without any additional HTTP request.
The first seems more easy, I can use the same technique for add/update/delete, with the price of doing an additional request to reload the listing.
The second is more cheap (no additional request), but require more logic to handle state for each add/update/delete case.
What is the right way to do it?
I would go with option 2.
In the general practice "getBooks" could be a huge array, and it is better not to requery the data from the DB when you already have it locally.
Just make sure you are deleting the book inside a try catch block, so if the delete doesn't go in the backend, you should alert the user.
I'm learning how to design a RESTful API and I've come across a quandary.
Say I have a POST endpoint to perform an action. The action has a certain cost associated with it. The cost depends on what the action is, particularly, on the body of the POST. For example, given these two requests:
POST /flooblinate
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
POST /flooblinate
{"intensity": 100, "colorful": false, "blargs": []}
Say the first one costs 500 and the second one costs 740.
I want to create a method which will tell me what the cost of posting the action will be. Since I am not creating or updating anything, it seems that GET is the most appropriate verb. However, a request body with GET should not have any meaning. This means that I'd have to put the data in the query string, say by URL encoding the request body to be passed to the POST:
GET /flooblinate/getCost?body=%7B%22intensity%22%3A+50%2C+%22colorful%22%3A+true%2C+%22blargs%22%3A+%5B%7B%22norg%22%3A+43%7D%5D%7D
This seems less than ideal since it's two data formats for the same thing. But the following:
POST /flooblinate/getCost
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
This also seems less than ideal since it's abusing the POST verb to query information, instead of to create or update something.
What's the correct choice to make, here? Is there any third alternative? Is there a way to rethink this design fundamentally which will obviate the need to make this choice?
Personally I'm not for adding dryRyn flags. I try to avoid boolean flags in general unless they're really required.
I've two ideas to cover this scenario:
One is to introduce state on the backend site, e.g. STARTED, FINISHED. When given resource action is submitted it has STARTED state and calculated cost which cam be viewed via GET method. Such resource may be modified with PUT and PATCH methods and is submitted when given method changes its state to FINISHED. Resources that didn't change its state for given amount of time are removed are their state is changed to other terminal value.
Second idea is to introduce a new endpoint called e.g. /calculations. If you need to calculate the cost of given action you just send the same payload (via POST) to this endpoint and in return a cost is given. Then resource send may be kept on server for some established TTL or kept forever.
In all the scenarios given (including yours) there's a need to make at least two requests.
The nicest choice here seems to be to have the endpoints return the info that need querying, and add a dryRun parameter to those endpoints. Thus:
POST /flooblinate?dryRun=true
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
Returns:
{"cost": 500, /* whatever else */
And then posting with dryRun=false actually commits the action.