简体   繁体   中英

Combining two ajax functions?

I have a website which has, amongst others, two pages: an event booking page and a login page.

My goal: I want to declare two Ajax functions, loginUser() and bookEvent(), that I can use on any page, also in combination. When the user clicks "login" on the login page, only the loginUser() function shall be executed, when user clicks "book event" on the event booking page, first it should be checked if the user is logged-in, then if he is not logged in he shall have the opportunity to login (invoking the loginUser function) and once he has logged in he will automatically have booked the event (invoking bookEvent function).

My question: How can I combine both functions in the latter case? And how can achieve that if the user is already logged in, on the events booking page only the bookingEvent() function gets fired when the user clicks on "book event"? I am not asking for the php code, I already know how to use both functions separately from one another and how to connect to the database!

Here is what I have come up with so far:

My two general customizable functions:

// LOGIN USER FUNCTION
function loginUser(login_query, param_response_dberror, 
param_response_failed, param_response_success) {

        $.ajax({
                type : "POST",
                url : "system/process-login.php",
                data : login_query,
                cache : false,
                success : function(ajaxresponse) {
                                if (ajaxresponse === 'db_error') {
                                    param_response_dberror();
                                }
                                if (ajaxresponse === 'failed') {
                                    param_response_failed();
                                }
                                if (ajaxresponse === 'success') {
                                    param_response_success();
                                }
                            }
                        });

} // /function loginUser();

// BOOK EVENT FUNCTION
function bookEvent (booking_query, param_response_dberror, 
param_response_failed, param_response_success) {

        $.ajax({
                type : "POST",
                url : "system/process-booking.php",
                data : booking_query,
                cache : false,
                success : function(ajaxresponse) {
                                if (ajaxresponse === 'db_error') {
                                    param_response_dberror();
                                }
                                if (ajaxresponse === 'failed') {
                                    param_response_failed();
                                }
                                if (ajaxresponse === 'success') {
                                    param_response_success();
                                }
                            }
                        });

} // /function bookEvent();

My page frontend:

<h1>Some event</h1>
<p>Some event description</p>

<a href="#">book event</a>

<div id="loginbox" style="display:none">
<input type="text" id="username" placeholder="username">
<input type="password" id="password" placeholder="password">
<a href="#" id="login_and_book">login and book</a>
</div>

First, it should be checked if the user is logged-in.

  • If he is not logged-in: Make the login box visible and when the user clicks "login and book" he gets logged in AND books the event . How can I combine both when the user clicks the button?
  • If he is already logged-in: Book the event.

This sounds like a poster-child for jQuery "Promises" , although it's complicated by the fact that even your "error" conditions look like "successes" at the AJAX layer.

You will need to maintain some browser-side state to indicate whether the user has successfully logged in or not, initially false , and set to true in the "success" branch of the loginUser function. You must of course also maintain this state on the server too, to avoid the possibility of the user bypassing the login requirement by hacking code on the client side.

I suggest also separating your success and failure conditions, and use promises to achieve "separation of concerns":

var loggedIn = false;

// returns promise that will be resolved by logging in via AJAX,
// or automatically resolved if the user was already logged in
function loginUser(login_query) {
    var def = $.Deferred();
    if (loggedIn) {
        def.resolve();
    } else {
        $.ajax({
            type : "POST",
            url : "system/process-login.php",
            data : login_query,
            cache : false
        }).then(function(ajaxresponse) {
            if (ajaxresponse === 'success') {
                loggedIn = true;
                def.resolve();
            } else {
                def.reject(ajaxresponse);
            }
        });
    }
    return def.promise();
};

Modify the bookEvent function similarly, and then when the "book event" button is pressed, use something like this:

function autoBook() {
    return loginUser(login_query).then(bookEvent);
}

Please note - this example is very incomplete . You will need to arrange for the appropriate query parameters to be sent, and for callbacks to be invoked based on the (eventual) results received from the promises.

AJAX is by definition asynchronous, so even if you could combine them into one function, there is no guarantee that either one would always be received first (eg: login might process AFTER booking, etc.). Your best bet is to put one inside the other -- specifically in the success callback.

This begs the question of how you are logging your users in, though; if you are using a redirect of some sort, then trying to combine them is pointless as after the user is redirected the previous AJAX call would be forfeit. If you are simply lumping the user login information onto the booking form, why not have a case server-side that checks if the user "lump" is in the data you sent it?

Here is a bit on "parallel" AJAX requests , but I think what you are really looking for is a "sequential" AJAX queue (which is demonstrated in the same link).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM