0

My Class looks like

function classUser() {
   var userName;
   var firstName;
   var lastName;
   var sessionid;
}

classUser.prototype.set_user_name = function (user_name) {
    this.userName = user_name;
}

classUser.prototype.set_first_name = function (first_name) {
    this.firstName = first_name;
}

classUser.prototype.set_last_name = function (last_name) {
 this.lastName = last_name;
}

classUser.prototype.get_curr_session = function () {
    return this.sessionid;
}

classUser.prototype.save = function () {

     $.ajax({
       type: "POST",
       url: "http://myapihost.com:8080/api/1.0/user/",
       data: JSON.stringify(this),
       dataType: "json",
       success: function (apiResponse) {
          var currSessionID = apiResponse.sessionId;
          this.sessionid= currSessionID;
        },
        error: function (apiResponse) {
          alert("error  : " + apiResponse);
          this.sessionid= "Error";
        }
    });
}

I call them as

    var User = new classUser();
    User.set_first_name(userFirstName);
    User.set_last_name(response.last_name);
    User.set_user_name(response.username);

    User.save();
    var currSessionID = User.get_curr_session();

Sometimes, get_curr_session is called before success: call.

Question : I tried returning sessionid from success itself so that save() function does the job. That is not working. hence i split across 2 functions.

Can I do it in one call itself? if I have use 2 functions - how do i make sure that it works all the time.

I could actually put assigning the currSessionID within success, however that breaks class sanctity. I have seen other solution like using "done", not sure if that would help here.

=======================================

I modified the code as below

classUser.prototype.save = function (callback) {

 $.ajax({
    type: "POST",
    url: "http://myapihost.com:8080/api/1.0/user/",
    data: JSON.stringify(this),
    dataType: "json",
    success: function (apiResponse) {
        var currSessionID = apiResponse.sessionId;
        this.sessionid= currSessionID;
        callback(null, currSessionID);
    },
    error: function (apiResponse) {
        alert("error  : " + apiResponse);
        this.sessionid= "Error";
        callback("error", null);
    }
});
}

When I call

User.save(mycallback);


function mycallback(error, sessId){
    if(error) {
        console.log("Some error occurred. Check code");
        return;// Something went wrong
    } else {
        console.log("Session : " + sessId);
    }
}

Is this good now?

Thanks Ajay

7
  • possible duplicate of How to return the response from an AJAX call? Commented Oct 2, 2013 at 8:05
  • I don't think those var declarations in classUser do what you think they do. Commented Oct 2, 2013 at 8:09
  • means? they do exactly what I want them to :) Commented Oct 2, 2013 at 8:38
  • @ThoughtfulMonkey In your provided code the var statments in the function classUser have no effect on your code. They bind the variables userName, firstName, ... to the scope of the function classUser, but because they are not used inside of it, they are effectively useless at that point. (var userName; has nothing to do with the this.userName) Commented Oct 2, 2013 at 8:49
  • 1
    @ThoughtfulMonkey no they don't have side effects, but if you want to show that/what properties you class has you should mark them in a different way e.g. using JSDoc. Or with defining a default value classUser.prototype.userName = null; outside of you classUser. Another note: I suggest to choose one naming conversation either user_name or userName mixing them often leads to errors. Commented Oct 2, 2013 at 9:47

3 Answers 3

3

That's because the success and error function of the ajax request are executed asynchronously.

To make sure this doesn't happen, you should add a callback to your save function that is called after the success or error functions ran.

classUser.prototype.save = function (callback) {

     $.ajax({
       type: "POST",
       url: "http://myapihost.com:8080/api/1.0/user/",
       data: JSON.stringify(this),
       dataType: "json",
       success: function (apiResponse) {
          var currSessionID = apiResponse.sessionId;
          this.sessionid= currSessionID;
          callback(null, currSessionID);
        },
        error: function (apiResponse) {
          alert("error  : " + apiResponse);
          this.sessionid= "Error";
          callback(apiResponse, null);
        }
    });
}

Then, when calling the save function, you can do something like this:

User.save(function(error, sessId) {
    if(error) {
        // Something went wrong
    } else {
        // Do whatever you need to do
    }
});

You should note that this will also run asynchronously. So if you want to work with the session ID, don't do that after the User.save(...) call, but inside the function.

Sign up to request clarification or add additional context in comments.

4 Comments

I think this is what I need. However, where do i define callback functions? (I havent used them before). right now it says callback not defined.
@ThoughtfulMonkey you pass it as parameter to your save function either as an anonymous function like you do at your success/error callback, your a reference to an existing named function.
I added some code. please let me know if this the correct way to go about it.
My new code worked perfect on Firefox. however didn't work on chrome :( and no error also in dev console.
0

$.ajax() issues an asynchronous call to the url specified in the options object. See the jQuery documentation at http://api.jquery.com/jQuery.ajax/

success is a callback function that is invoked when the call is completed and all the response stream is read by the browser so basically in most of the cases the callback (updating the session id) will execute after you try to retrieve it.

3 Comments

The success callback is always called after the current execution flow (like writing setTimeout(function() { .... },0);) If it is somehow executed before the var currSessionID = User.get_curr_session(); then i would consider it as a bug, because it conflicts in how async call should/do work.
You're right. I was considering the possibility of calling $.ajax() with cache: true and thought that the browser wouldn't issue the async request but instead serve the cached version thus executing synchronously. At least this is how .NET tasks work and I extrapolated to JS promises, but I'm most probably wrong ;)
Also with cached it should be called after the current execution flow. Promises/A+ [...]this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called [...] jQuery has various parts in the code to ensure this e.g. // (IE6 & IE7) if it's in cache and has been retrieved directly we need to fire the callback where they use setTimeout( callback ); If api is defined as async it should always behave that way (or provide a parameter/alternative to make it sync).
0

I think what is happening here is that the default ajax call is async which means that the code var currSessionID = User.get_curr_session(); can execute before the success call completes.

You have a couple of options, you can try and update your code to be more async capable, using callbacks or other methods, or specify that you want your ajax call to be synchronous.

1 Comment

You should not suggest to make the ajax call synchronous, because this could/will lead into bad impact on the responsiveness of the browser.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.