0

When a user clicks the button we should check they are logged in via an ajax request. Only after the ajax request has returned should my form show.

The ajax request returns an error (intentionaly for illustration purposes) yet my form still shows.

How can I modify my code so the display_form() will only run after check_loggedin() has completed?

Thank you very much.

PS I am aware there are various posts about promises but despite trying I have not managed to understand them - it would be really helpful if someone could please modify my code so I understand where I'm going wrong - thank you.

$(document.body).on('click', "#check_logged_in_show_form_if_true", function(){


 check_loggedin().then(display_form());

});

function check_loggedin(myurl) {


 return $.ajax({
  method: 'get',
  url: 'https://www.this-domain-will-cause-ajax-request-to-error.com',
  data: {
   foo: 1,
  },
  traditional : true, 
  beforeSend: function() {
   
  },
  success: function(data){

   console.log('logged in - ok to show form');
   return true
  },
  error: function(data){
   
   // not logged in prompt user to sign in
   console.log('ajax failed - do not show form');


   return false
  }
 });

};


function display_form() {

 $('#myform').show();

};
<div class="alert alert-success" id="myform" style="display: none;">
 
 Only show this form if ajax request is successful

 <input type="text" name="input" placeholder="" value="" class="form-control" >
 
</div>


<hr />


<span class="btn btn-primary" id="check_logged_in_show_form_if_true" >Display form if ajax request is successful (form should not show)</span>



<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
happysailingdude
  • 185
  • 1
  • 14
  • 2
    `.then(display_form())` -> `.then(display_form)` (there's definitely a dupe target for this) – Andreas May 29 '20 at 10:29
  • Thank you so much! How would I modify the promise so if the ajax errors then display_form() will not be called (but an alternate function is called eg to prompt the user to log in) please? – happysailingdude May 29 '20 at 10:55
  • 1
    To clarify Andreas' comment: writing `display_form()` means execute the display_form function **now** - the moment that code is run, and pass the **result** of that function to the `then()` function. Whereas `then` expects to you give it a **reference** to the function, so that later, when the Promise is resolved, it knows which function to run at at that moment. To pass the reference, you simply write the name of the function without the brackets. – ADyson May 29 '20 at 10:56
  • 1
    To handle errors, use the "catch" callback: https://api.jquery.com/deferred.catch/ (or you could add a second function to `.then()`, as also mentioned in that same link). – ADyson May 29 '20 at 10:59
  • I'm not able to find the dupe target... :/ Only this one: [Why is the method executed immediately when I use setTimeout?](https://stackoverflow.com/questions/7137401/why-is-the-method-executed-immediately-when-i-use-settimeout) – Andreas May 29 '20 at 11:11
  • Thank you both - I am so happy to have got this working! The info about .catch really helped too. A quick follow up question if I may please.. I'm guessing that the outcome of the ajax call (success or error) is passed out of check_loggedin. If check_loggedin did not contain an ajax call but some other code (that is slow to run) what would I add to check_loggedin so that the promise would still work please? ie so that display_form would only fire once check_loggedin had finished? – happysailingdude May 29 '20 at 12:42
  • 1
    "I'm guessing that the outcome of the ajax call (success or error) is passed out of check_loggedin"...sort of. The Deferred (or Promise) object is returned from the check_loggedin function. At that point the promise is still pending (not resolved or rejected). it's then up to code receiving the object to append then, catch or done callbacks to be able to know the result of the promise at the (later) time when it completes. The promise will then fire one of the callback functions given to it (which one it fires depends if the promise is resolved or rejected (i.e. suceeds or fails). – ADyson May 29 '20 at 14:48
  • 1
    "If check_loggedin did not contain an ajax call but some other code (that is slow to run) what would I add to check_loggedin so that the promise would still work" ...you'd have to return some other kind of Promise object, as the representation of some other kind of asynchronous task. A Promise can wrap round almost any code you like. https://javascript.info/promise-basics has a nice intro to the whole concept and some simple examples (e.g. their initial example is as simple as just setting a timeout to wait a few seconds and do nothing. The promise resolves when the timer expires!). – ADyson May 29 '20 at 14:49

0 Answers0