1

I am struggling to find a nice logical way of representing this pseudocode in javascript with async calls:

This is controller pseudo code:

// get the data for the main page, server will return login details if not logged in
model.getdata(mypage);

// keep trying to get a login until the user successfully logs in
while (model.loggedin() === false)
{
    // show the login form
    view.showloginform(model.data);
    // and push that login to the server
    model.trylogin(view.login.userdata);
    if (!model.loggedin())  // show the error to the user and they will click ok
        view.showloginerrordetails(model.loginresponse);
    else  // try to get the main page data again
        model.getdata(mypage);
}

// now we are logged in so we can show the main page
view.showmainpage(model.data);

model.getdata is async while waiting for the server to respond view.showloginform is async while waiting for the user to fill the form in model.trylogin will be async while waiting for the server. etc

So obviously my loop wouldn't work if any of the calls were async. And they all are

I think its easy with closures when the loop only happens once, but how would you write all this in a function when the loop could run through several iterations ?

This is just a simple example but I want to support more complex workflows using the same ideas.

I'm really interested in how people structure code like this in javascript so the code is readable and elegant etc.

user2728841
  • 1,333
  • 17
  • 32
  • I'm just a bit confused at the overall goal of your pseudo-code, think you could explain a bit more the end goal. – tymeJV Feb 14 '14 at 19:38
  • OK so lets say the user requests a page on a site that requires a login. Their session has timed out so the server returns data saying so. Then we have to do the login process which is (a) show the login form (b) user clicks ok so send to server to log them in and then (c) try to get the data again for the page they originally requested. The pseudo code represents this cycle. User could get their password wrong many times. But I don't see an easy way of structing this when each action in my pseudo code goes async. – user2728841 Feb 14 '14 at 19:46
  • The way you described above seems pretty straight forward. The users session is gone, so there is no `while` loop for waiting for the user to log in again, its simply just a matter of waiting for the user to login. You can track the last page the user was on before the login action was requested, and upon successful login, redirect back to the last page – tymeJV Feb 14 '14 at 19:59

2 Answers2

1
// capture form submit
function submit(callback) {
   //create ajax request and post to server
};

function callback(result) {
   // inspect result
   if (result.valid) {
      //do cool logged in stuff
   } else {
      //display whatever the error was
   }
}

Since you're using asp.net MVC you can also bind the fields in the view so that they will display any errors. This way you wouldn't need to use javascript just have the login form post directly to the server and do the validation and redirection there. To do something like this checkout ASP.NET MVC: Custom Validation by DataAnnotation and http://msdn.microsoft.com/en-us/library/ee256141(v=vs.100).aspx

Community
  • 1
  • 1
Nimnam1
  • 515
  • 4
  • 12
  • Thanks. I'll need to put some thought into this. I'm not using asp.net mvc - just similar concepts in a SPA web app. So there is no rendering done on the server, just metadata that defines each screen and thats painted into html by javascript. So its 100% ajax single page and what I'm looking to do is find a way of encapsulating complex workflows into single javascript functions - and this is a simple example of how I'd like the function to look - if only it could work when the calls are async – user2728841 Feb 14 '14 at 20:13
  • okay cool, just make sure that the ajax call sets, it's callback to tbe the callback passed into the submit. Good luck – Nimnam1 Feb 14 '14 at 20:15
  • I suppose the point of the question is this: when you have complex workflows that say get this data, show this to the user, get some more data, if this then that, its not possible with any async stuff to represent all that flow in a single function, and the JS gets increidbly messy very quickly. So I've been looking at "queue" solutions as we as interpreting workflow language, but I really wondered since this must be a common problem whether the JS community have already come up with ideas for laying out this logic more simply. – user2728841 Feb 14 '14 at 20:27
  • have you looked into deferred and promises? – Nimnam1 Feb 14 '14 at 20:35
  • Yes, but how would you "if" and "while" and step backs or whatever in those situations? Actually I've just been googling for workflows and I think it would be quite easy to knock up a js class that does workflow including looping, conditions, step jumps etc.. lots of ideas brewing (and there's a few workflow libraries out there too). – user2728841 Feb 14 '14 at 20:49
1

Async actions could be handled in 2 ways:

  • Callbacks
  • Custom events

@Nimnam1 gives you an idea of the callbacks

model.getdata(mypage, dataGotten);

function dataGotten(result) {
    if (result.success) {
      // handle success
    } else {
      // handle failure
    }
};

in your model.getdata functions/method, you would have to call dataGotten() callback function upon completion and pass the result argument object.

With custom events, you would just do

model.bindEvent('submit', dataGotten);

Here is a good intro to custom events http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/ . They are much more graceful, flexible and maintainable for large code base.

i--
  • 4,349
  • 2
  • 27
  • 35
  • Thanks. Yes this is a good way of making the code readable. I've made significant progress today on the topic but I'm going to hold off posting a final update here for a week or two because I have lots of ideas brewing and also I have more complex workflows to approach. So I'll come back and add an EDIT section with what I found then :).. thank you – user2728841 Feb 15 '14 at 12:57
  • @user2728841, sure, I would be interested to see your findings. – i-- Feb 15 '14 at 13:15