How to distinguish koa ctx is multipart/form-data type or not? - koa

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
}
))

Related

dispatch ngxs action in switchMap ignoring the return value

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

How to get the result of a asynchronous action in NGXS?

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.

What's the difference between Promise and AJAX?

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'));
}

Single method to handle post or loading view in laravel

I am trying to understand how POST routing will work. I have a method defined, signup(), and I want to use the same method to detect if the user wants to sign up (so load the signup view) or if the user already in the signup view (form) and posting his details to register.
Can this be done in one function in laravel? if yes, then how? Is this controlled by Routes and if yes, can someone please clarify this with an example?
Laravel documentation is really confusing for beginners.
Thanks in advance,
While this is possible but it's not recommended way to do that, you should keep your routes separated from each other (using GET and POST) and should use different methods as well. Basically any form submission should use POST request (using POST HTTP method) and to show the form just use a GET method but anyways, you can do it (what you have asked for) like this way:
// Declare the route
Route::post('signup', 'UserController#signup');
Now in your signup check for the submit button to make sure that, the form is submitted, so if the input submit is available in the $_POST array then the form is submitted otherwise, it's not submitted but an empty form was presented to the user or a failed validation redirect happened. Maybe something like this:
public function signup()
{
if(Input::has('submit')) {
// It's a submission, so Validate submitted Form data
// if invalid then redirect back with inputs and errors
// Otherwise save it
}
else {
// show the form
return View::make('user.signup');
}
}
Don't do it
This is just an idea but, it's a bad idea, just think about what happens if you have errors on your form and you want to redirect back then the whole thing would become messy, the controller method will become totally unmanageable after a while because it does many things while it should have only one specific responsibility.
I have this practical experience, because, I used to think that, if I can use one function for loading and saving and even also updating then it would be smart but to be honest it was stupid and obviously it's an anti-pattern, not the best practice, against KISS (Keep It Simple Stupid) principle. This kind of coding is a bad idea and you'll suffer for it in future and you would not dare to touch the code thinking that if you brake anything because you'll be confused by your own code.
Just use separate methods to show a form and save submitted data, Also check this on slideshare.
Yes, you can use one route to do it:
Route::any('signup', 'SignupController#signup');
Or two routes pointing to the same url:
Route::get('signup', 'SignupController#getSignup');
Route::post('signup', 'SignupController#postSignup');
In both cases you'll need a controller:
Here it is with all related methods:
class SignupController extends Controller {
// This one is for Route::any()
public function signup()
{
if (Input::has('email'))
{
// create your user
}
return View::make('signup');
}
// those two are for the second option
public function getSignup()
{
return View::make('signup');
}
public function postSignup()
{
// create your user
}
}

What should I name the actions for ajax requests?

Let's say I have an action:
def result = Action { Ok(views.html.home.result()) }
From result view I want to send ajax requests to the server. What's the standard (if any) way to name the actions that receive such the ajax requests? It might be something like:
def getResultAjax(param1: Int) = //....
To my mind, it look clumsy.
Your ideas?
There's no such convention in Play, anyway action's name should rather contain info about returned data i.e. listOfBooks then just getResult.
On the other hand when there's a lot of different methods (some common, other for ajax requests) it can be cleaner if you'll use ajaxListOfBooks or create BooksAjax controller to handle AJAX request only.
BTW: Purists would say that the requests REST's HTTP methods should also be taken into account, and then action names can be simplified, pseudo routes:
GET /ajax/books Books.list
GET /ajax/books/:id Books.get(id)
PUT /ajax/books Books.create
POST /ajax/books/:id Books.update(id)

Resources