In Ember.js, I have a Controller property function which calls an json request, and it needs to have multiple observables, as there are multiple conditions where I need to update the json data.
This works great when only one of the properties observed changes, however, when there is a case that multiple properties goes through a change, this is causing the json request to fire off multiple times with the identical request. How can I limit the amount of times that this function fires off to only once?
I kept the question general to have it be applied to other future cases, however, if it is pertinent, the case that I'm using it for is in the case of Pagination, where I need to observe the page index, the page size, the sorted by, and the sort order.
The simplest approach would be to set a flag on the controller when it is about to make the request, clear it when the request completes, and check the flag in the observer to decide whether to generate the ajax request.
Related
I'm having a trouble wrapping my head around following concept.
I'm sending OSC messages to query status of instruments in Ableton, so I have emmiter/receiver combo going on. Now, thing is that I'd like to avoid having to keep up some sort of global state and wrap everything around this.
and I do communicate with Ableto in following fashion:
sender.emit("/live/device", queryData);
receiver.on("/live/device", function(responseData){
// process response here...
})
So you can tell that I'm not really sure when I got data back and cannot really sequence new queries based on responses.
What I'd like to do is to simply
query number of instruments on ONE certain channel
get number back
query parameters of each instrument of that channel based on first query
receive parameters back
But problem is that I have no idea how to wrap eventListeners to respond to these queries, or rather how to sequence them in way that is non-blocking and yet still avoiding having some sort of global state going on.
Querying data and storing Promises to be resolved by eventListener seems like a solution, but then I'm stuck on how to pass them back to sequence.
After some research, it seems that this kind of behaving breaks the whole concept of event listeners, but then I suppose the whole point is to have some global state to keep track of what is going on, right?
Event listeners are telling you some asynchronous action coming from a user action or any other interrupt. Depending on the API you are facing, they might have re-used event listeners for replies instead of providing a promise or callback return for the send API. If the server has multiple clients interacting with it, it might want to tell all clients at the same time when their state changes as well.
If you are sure there is no way to directly provide a callback in the send method for a reply to your request or a request does not yield a promise that resolves with the reply at some point, there are usually workarounds.
Option 1: Send context, receive it back
There are APIs that allow sending a "context" object or string to the API. The API then sends this context to the event listeners whenever it answers this specific question along with their payload. This way, the context part of their payload can be checked if it's the answer to the request. You could write your own little wrapper functions for a more direct send/reply pattern then.
Option 2: Figure out the result data, if it fits your request
If the resulting data has something specific to match on, like keys on a JSON object, it may be possible to find out what the request was.
Option 3: Use state on your side to keep track of everything
In most cases where I have seen such APIs, the server didn't care much about requests and only sent out their current state if it was changed by some kind of request. The client needs to replicate the state of the server by listening to all events, if it wants to show the current server state.
In most situations where I faced this issue, I thought about Option 1 or 2 but ended up with Option 3 anyways: Other clients or hardware switches might interfere with my client UI and change the server state without me listening on that change. That way I would loose information that invalidates my UI, so I would need to listen and replicate the state of the server/machine/hardware anyways.
I have an action, reducer, and service for some resource.
Let's assume in this case the resource is a cart, from which a user can have multiple of.
I have the following methods, getCartInformation, getCarts, getCartCount.
And I have the following API's, fetchCartInformation, fetchCarts, fetchCartCount.
getCarts returns the cart id's which are needed for getCartInformation and getCartCount
The question is, what would you do to avoid making multiple fetchCarts calls to the API whenever you call getCartInformation or getCartCount as a side-effect
Would you extend the API library with a fromCache flag, so that fetch*** has that option available.
Would you set a counter on the API library of "calls while querying the endpoint" and then just re-trigger the callers of the functions?
Would you add a check on the action to see if getState has already the cart, and if not query and re-trigger the function (might have 2 or more concurrent calls at the same time for a slow endpoint)?
Let's now assume that multiple components might trigger the getCartCount call, sometimes you want to call the endpoint when the component appears in the page and sometimes they all get called in the initialisation of the app because the components are all being added. In this case this will call the endpoints getCarts and getCartCount quite a couple of times.
Is there some kind of "redux-way" to catch that there's multiple calls to one method before it has already resolved?
Would you set a counter of calls on the getCarts action?
Would you make the action getCartCount depend on the getCarts promise response, and have a check on the getCarts action?
I know it's a bit complex and long question, but if there's more or less detail needed please let me know.
I do not understand why you should call getCarts whenever you call getCartInformation. Common use case is: (1) user see list of cards (by getCards) and (2) user click on one of them and see card info (by getCartInformation with id of selected card). Looks like you do not need to call getCards one more time.
It is usual to divide list of cards into pages. So you always have start, offset, total fields as service fields at every getCards call, so you do not need getCartsCount at all.
When I applied any kind of cache, it was reasonable to me to make it transparent for Redux, i.e. Redux action perform API call in usual way, and API layer decides (under the hood) should it send real ajax call or should it return data from cache.
Say there is such a case:
In the state, there is a list, which corresponding to multiple rows in a table on the UI. There are multiple api calls, one for each item (row), which will retrieve the latest status, and update one item in the list.
In such case, I can understand that callback method will be better than direct call of setState. However, I still don't know whether multiple calls of the callback will be synchronized.
For example, whether the following situation will happen?
callback 1 reads list
callback 2 reads list
callback 1 updates list(0)
callback 2 updates list(1)
callback 1 writes back
callback 2 writes back
In such case, the update from 1 might be lost, which is typical for read-modify-write.
I still do not clearly understand your problem, perhaps if you could provide some code it would be better.
But if you meant to call a fetch function multiple times and setting the state once it's arrived, then you should be safe to assume that a setState should not override another, whether were your calls done asynchronously or synchronously.
But in any case, you shouldn't as a front-end send this much requests at once, you should request all the data from the server
We are creating an React application, which has lists with basic CRUD operations in multiple places. The basic example, of course is:
Fill input to have name for the item, click submit
Send request to server
Fire callback on success
Update list with item using response data
I want this operation to be fully optimistic:
Fill input to have name for the item, click submit
Update list with item using given name
Send request to server
Fire callback on success
Update item in the list with response data
So, in the first example we would simply make an item out of the response and update app state. In second example we make the item and when response comes back, we need to find the right item.
The items have id's when they come back from the server. If item has an id, updating, of course, is very simple. The problem with the second example is, that we don't know the backend id for the item.
I have personally solved the issue by giving a frontend id, which is only used for referring to right element on callbacks. Me and my colleagues don't really like the approach, because it is a bit... messy.
What would be an appropriate, efficient pattern for handling this kind of case?
First of all I am glad you have found a place for optimistic UI in your project ;)
Concerning your question: what you're doing is indeed a totally valid solution. Setting frontend ID is totally fine. But I, in the similar cases, do it a bit differently. Instead of updating the item on your last step, I would again update the whole list. The point with this is that you get the response with the full list anyway so why not to use it? It solves two issues:
no need to rely on frontend ID or any other way of marking/storing the item for that matter;
in case there is a possibility of multi-threaded updates to the list from different clients (in the timeframe between your client gets the list and clicks submit), updating the whole list will keep it up-to-date much better;
Note though that updating a large list might have an impact on performance after all. At the same time, you don't need to parse the list after getting the response so you save some time here.
So compare both solutions and make a decision based on the best possible outcome for your users ;)
When developing web applications I generally see two ways people perform crud and sync the view.
Here are the high level examples which use ajax.
1- Method one
A create operation could involve a POST request and on success of that just do another GET and fetch all the data and rerender you view.
A delete operation is similar just do another GET on delete success
2- Method two
A create operation could involve a POST request which would return just the inserted id and on success of that do NOT do another GET request rather append the data that was just was sent into the current list of items in your view.
A delete operation would return the id and on success search the element that has that id and delete from DOM or array of items etc.
I am interested to know what is usually more preferable, method two for example saves a GET request but it comes at a lot of complexity in the front-end code as now you have to write the code the figures out which item needs to be delete updated etc and if the server needs to add more data to the item that was created before it is displayed this will make method two harder. On the other performance will be better if the GET requests takes a long time to load.
In my projects depending on the complexity I may use either method depending on the situation but I do believe it's better to stick with one approach.
Go with method 2. Manipulate your HTML as soon as the user requests the action. Your users expect whatever action they take on your page to have immediate feedback. You can't afford to wait a quarter of a second to a full second waiting for your back-end to respond before you provide this feedback. If you do, the user will most likely try the action again - this is just a natural instinct all users have today.
This brings up the question: what if my operation doesn't succeed and is rejected by the back-end? You should also write your code so that on error response, you are undoing the view changes you made when the initial action was detected and that you are providing a message (whether showing a bright DIV error box or alerting the user through a pop-up) to the user that their action did not complete successfully.
This gives you the best of both worlds. Your user gets a smooth UI experience, and you provide a way of informing your users if their requests are rejected.
Here's an example of how you would write this using jQuery. But this technique applies to any JavaScript framework (Backbone, Angular, etc...)
$('#button').on('click', function(){
//do some DOM changes that tell my user their action succeeded
$.ajax({
url: 'http://myendpoint.com',
type: 'POST',
data: {key: 'value'},
error: function(){
//undo my DOM changes since request failed
}
});
});