Both promises and AJAX calls are asynchronous operations. A GET/POST request could be made with both. << Edit: that's a WRONG statement
So what's the difference between them? And when would be best to use one instead of the other?
Also, one more thing:
Recently I encountered a promise which had an AJAX in its body. Why put an async operation inside an async operation? That's like putting a bread loaf in a bread sandwich.
function threadsGet() {
return new Promise((resolve, reject) => {
$.getJSON('api/threads')
.done(resolve)
.fail(reject);
})
}
jQuery is used here. And the AJAX call has Promise behavior and properties. I didn't get that earlier but here are my thoughts:
We can do something in the Promise. Then use the AJAX call and in the done function pass the resolved Promise logic. Specifically in this example there is none.
Now I see that I had confused both. They're pretty much 2 different things. Just because they're asynchronous, doesn't mean they're interchangeable.
==============
EDIT 2: Just some materials I found useful:
Promise Anti-Patterns
You are confused about promises and Ajax calls. They are kind of like apples and knives. You can cut an apple with knife and the knife is a tool that can be applied to an apple, but the two are very different things.
Promises are a tool for managing asynchronous operations. They keep track of when asynchronous operations complete and what their results are and let you coordinate that completion and those results (including error conditions) with other code or other asynchronous operations. They aren't actually asynchronous operations in themselves. An Ajax call is a specific asynchronous operation that can be used with with a traditional callback interface or wrapped in a promise interface.
So what's the difference between them? And when would be best to use
one instead of the other?
An Ajax call is a specific type of asynchronous operation. You can make an Ajax call either with a traditional callback using the XMLHttpRequest interface or you can make an Ajax call (in modern browsers), using a promise with the fetch() interface.
Recently I encountered a promise which had an AJAX in its body. Why
put an async operation inside an async operation? That's like putting
a bread loaf in a bread sandwich.
You didn't show the specific code you were talking about, but sometimes you want to start async operation 1 and then when that async operation is done, you want to them start async operation 2 (often using the results of the first one). In that case, you will typically nest one inside the other.
Your code example here:
function threadsGet() {
return new Promise((resolve, reject) => {
$.getJSON('api/threads')
.done(resolve)
.fail(reject);
})
}
is considered a promise anti-pattern. There's no reason to create a new promise here because $.getJSON() already returns a promise which you can return. You can just do this instead:
function threadsGet() {
return $.getJSON('api/threads');
}
Or, if you want to "cast" the somewhat non-standard jQuery promise to a standard promise, you can do this:
function threadsGet() {
return Promise.resolve($.getJSON('api/threads'));
}
Related
There must be a standard way to solve this, but I haven't found anything yet. I am probably not phrasing my search correctly.
I have a search input field and as is good practice, I use the switchmap operator to cancel previous http requests, when the user keeps typing.
I have based this off the example in the ngxs documentation:
this.actions$
.pipe(
ofActionDispatched(SomeAction),
debounceTime(2000),
distinctUntilChanged(),
untilDestroyed(this),
switchMap(() => {
return this.store.dispatch(new SomeOtherAction());
})
).subscribe(() => {
});
SomeAction is dispatched every time the user types something in the input field and saves in in the store (that's why SomeOtherAction has not constructor parameter).
Is there a better way to do this without having this empty subscribe block? This looks like an anti-pattern.
Another way you could consider is to only dispatch the action to change the searchText in the state after you debounce etc.
Using the valueChanges Observable on the search input form control you could pipe through a debounce/distinct/filter or whatever combination suits your purposes before calling store.dispatch with your action to modifiy the state.
Then you'd only modify the state the minimum required times rather than each key press and could also call the HTTP request from there (and I don't think you'd need the action stream subscription in the component).
Doco for Angular Form valueChanges here
I want to perform an action based to the result of an asynchronous NGXS action.
In a Angular frontend app I'm using NGXS for state management. Some of the actions involve talking to a backend via REST calls. Those actions are implemented as asynchronous actions, with the reducer functions in my state classes returning an Observable.
What I'm looking for is a way to get hands on the result of the backend call, to be able to perform some action.
One use case I'm trying to implement is navigation to just created objects: Business objects are created in the frontend (Angular) app with a couple of domain properties. They get persisted in the backend, and as a result an ID for this object is created and returned to the frontend, and incorporated into the NGXS store. As a direct response to this, I'd like to navigate to a detail view for the new object. To do so, I need
(a) the information that the call has been returned successful, and
(b) the answer from the backend (the ID in this case).
Another slightly more complicated use case is the assignment of a number of tags to an business object. The tags are entities by themselfes, and have an ID each. In the UI, the user can either pick existing or add new tags. Either way, multiple tags can be added in a single step in the UI, which means I have to
call the backend for each new tag to create the ID
after all missing tags are created, update the business object with the list of tag IDs
In general, there are use cases in the frontend that depend on the result of a backend call, and there is no clean way to find this result in the store (although it's in there)
I know I can subscribe to the Observable returned from the store's dispatch method (as shown in asynchronous actions).
I also know about action handlers. In both cases I can attach code to the event of an action finished, but neither option enables me to get the result of the backend call. In the fist case, the Observable carries the whole store, while in the latter case I get the original Action, which is unfortunately missing the essential information (the ID).
The part you're missing here are selectors. Dispatching actions is not supposed to give you back a result. The only purpose of the Observable returned by store.dispatch() is to tell you when the action's handlers are done.
To get to the data returned by your calls to the backend, you have to patch the state inside your action handler. And then, outside of your state, you can access the data using store.select() or store.selectSnapshot() depending on what you need. Your state class should look somewhat like this (untested):
#State()
export class SampleState {
#Selector(SampleState)
sampleSelector(state) {
return state.sampleObject;
}
#Action(SampleAction)
sampleAction(ctx: StateContext<any>, action: sampleAction) {
return sampleBackendCall(/* ... */).pipe(
tap((result) => {
ctx.patchState({ sampleObject: result });
})
);
}
}
Now you can access this result where ever you need using the Store. For the use case of navigating to an element after its creation, you can combine a subscription to store.dispatch() with a store.selectSnapshot() like this:
store.dispatch(new SampleAction()).subscribe(() => {
navigateTo(store.selectSnapshot(SampleState.sampleSelector));
});
Note that in this easy case a selectSnapshot is perfectly fine, as we only want to get the value we just finished writing into the state. In most cases though, you will want to use store.select() or the #Select() decorator because they return Observables which enable you to also correctly display changes in your state.
That said, I'd like to add that if saving data inside the state is not necessary for you at all, then probably NGXS is the wrong library for you in the first place and you could as well just use an ordinary angular service directly returning the result of the backend call, like suggested in the comments.
So i'm using koa2,
if this request is multipart type, believe i need to process
ctx.request.body.fields
otherwise i process
ctx.request.body
So what's the best way to distinguish and handle these 2 cases ?
I guess my point of view is, if you're needing to check for a form submission as well as other activity, then perhaps your endpoint is doing a bit much? It very much depends on your use case of course, but keeping form data and other content types separate may be a clearer API.
Having said that, I don't see any reason to get more complicated than checking for the presence of fields. koa-body is a great way to go about this.
One thing you might like to consider is using the middleware stack to your advantage. For example, only do stuff if there's a form submission but allow other actions to take place:
router.post('/', koaBody({ multipart: true }),
async (ctx, next) => {
if (ctx.request.body.fields) {
// Handle form if present
}
await next() // Pass control down the stack
}
))
I am very new to redux and redux-observable so I would like to ask for some advice.
I am using redux-observable with rxjs to handle all my side effects which works very well.
I am using redux-form to handle form input and form validation that works also very well.
My problem is to integrate them together. My understanding is that redux-observable runs parallel to my ordinary actions creators so the action I invoke when I submit the form will always return without an error and my parallel running observable will yield a different action down the line if there was any issue with the submittion so I am not sure how I could handle it properly.
I found the following library. https://github.com/salsita/redux-form-actions
that looks like using a HOC to wrap the action with a promise. I am just wondering if that is the right way to go about it and how it works.
Can someone from the redux-form community check it out and let me know if it looks good. I do not have enough knowledge to make a call at this point as I wrote my first form today and I do not with to go down the wrong path.
Also an explanation how this works would be gratelly appreciated too / if there is a better approach.
I appreciate any comment or notes!
Thanks a lot !
The gist is, within onSubmit, pass a Promise's resolve/reject functions to a dispatched action. await on that promise. then, in your epic, call resolve/reject as needed to resume onSubmit's flow.
here's my PR explaining how it works, with a runnable example: https://github.com/redux-observable/redux-observable/pull/490
I have developed some websites and I always stumble a the same point: multiple ajax calls. I have a main page where all the content is loaded asynchronously. When the page is loaded, there are four INDEPENDENT calls that "draw" the page by areas (top, left, right and bottom) and while it is loaded I show to the user the typical ajax spins. So, when a request is received by the browser I execute the callback and the different areas are drawing at different time. The fact is that the answer for the server sometimes are mixed up, I mean, the answer of top is drawn in the left or vice-versa.
I've tried some solutions like creating a timestamp in each request to indicate to the browser and server that each request is different.
Also I've tried to configure some parameters of cache in the server, in case.
The only way in which works has been including the request2 in the callback of the one, etc.
Anyone knows the proper way to do it or ever has beaten this issue?? I don't want to do chained request.
Thanks
Here is an example of what I mean:
$(document).ready(function() {
$.get('/activity',Common.genSafeId(),function(data){$('#stream').html(data);$("#load_activity").addClass("empty");});
$.get('/messages',Common.genSafeId(),function(data){$('#message').html(data);$("#load_messages").addClass("empty");});
$.get('/deals',Common.genSafeId(),function(data){$('#new_deals_container').html(data);$("#load_deal").addClass("empty");});
$.get('/tasks',Common.genSafeId(),function(data){$('#task_frames').html(data);$("#load_task").addClass("empty");});});
And the html is a simple jsp with four container each one with a different id.
CLOSURES
Closures are a little mind-blowing at first. They are a feature of javaScript and several other modern computing languages.
A closure is formed by an executed instance of a function that has an inner function (typically an anonymous event handler or named method) that needs access to one or more outer variables (ie. variables that are within the outer function but outside the inner function). The mind-blowing thing is that the inner function retains access to the outer variables even though the outer function has completed and returned at the time that the inner function executes!
Moreover, variables trapped by a closure are accessible only to inner functions and not to the further-out environment that brought the closure into being. This feature allows us, for example, to create class-like structures with private as well as public members even in the absence of language keywords "Public" and "Private".
Closures are made possible by inner functions' use of outer variables suppressing javaScript's "garbage collection" which would otherwise destroy the outer function's environment at some indeterminate point after completion.
The importance of closures to good, tidy javaScript programming cannot be overstressed.
In the code below the function getData() forms, at each call, a closure trapping id1 and id2 (and url), which remain available to the anonymous ajax response handler ($.get's third argument).
$(document).ready(function() {
function getData(url, id1, id2) {
$.get(url, Common.genSafeId(), function(data) {
$(id1).html(data);
$(id2).addClass("empty");
});
}
getData('/activity', '#stream', '#load_activity');
getData('/messages', '#message', '#load_messages');
getData('/deals', '#new_deals_container', '#load_deal');
getData('/tasks', '#task_frames', '#load_task');
});
Thus, rather than writing four separate handlers, we exploit the language's ability to form closures and call the same function, getData(), four times. At each call, getData() forms a new closure which allows $.get's response handler (which is called asynchronously when the server responds) to address its DOM elements.
Make sure you have different callbacks for each ajax call, it sounds like you are trying to use the same function for all four, thus when they are called out of order (because they take different amounts of time server-side), they are rendering in the wrong place. If you insist on using the same function for all your callbacks, then you have to put something in the payload so that the callback knows where to render to.