1

I have a form where a subscriber can select the newsletters they want to recieve and then an AJAX form will send the results to Exact Target and add the subscriber to every list the subscriber want to be added too.

I have a PHP foreach loop setup to handle this.

<?php foreach ($listNumbers as $item): ?>
            var xmlData = 'Ths is the ET API call';
            $.post('ET url for API call'+xmlData);      
        <?php endforeach; ?>    

After the loop(s) run the user is sent to a thank you page like this.

$(document).ready(function() {
location.href = "thank you url";
});

Everything works.. for the most part. I'm using document ready because I'm wanting to give the loop enough time to submit the API call. Is there a way to detect when the $.post function(s) are complete? If it is sucessfull? and then send the user to thank you page?

I'm finding that the location href is sending some users to the thank you page before the code has a chance to run.

Thanks, Michael

mkrisch
  • 105
  • 2
  • 12
  • Using PHP to loop and create jQuery $.post's .. why? – Blake Apr 05 '12 at 15:41
  • There has to be a better way of doing what your doing! – 472084 Apr 05 '12 at 15:44
  • If the subscription script is on your site you should send it the array of checkboxes in a single POST to reduce the amount of open connections on your server. If the subscription scripts are on other servers the browser will block the posts because of cross domain scripting restrictions. – Alex L Apr 05 '12 at 17:51

3 Answers3

2

http://api.jquery.com/jQuery.post/

There's a callback that tells you it's finished

jQuery.post( url [, data] [, success(data, textStatus, jqXHR)] [, dataType] )
  • url - A string containing the URL to which the request is sent.
  • data - A map or string that is sent to the server with the request.
  • success(data, textStatus, jqXHR) - A callback function that is executed if the request succeeds.
  • dataType - The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html).

Sample script, you need to keep track that all requests have finished, although I would strongly suggest you write a new server side call that you can call just once, if you can.

var xhrCount = <?= count($listNumbers) ?>;
<?php foreach ($listNumbers as $item): ?>
   var xmlData = 'Ths is the ET API call';
   $.post('ET url for API call'+xmlData, null, function() {
       xhrCount--;
       if (xhrCount === 0) {
           location.href = 'myurl'
       }
   });      
<?php endforeach; ?>  

Not sure, what could be wrong with your count() but you can count it yourself;

var xhrCount = 0;
<?php foreach ($listNumbers as $item): ?>
   var xmlData = 'Ths is the ET API call';
   xhrCount++;
   $.post('ET url for API call'+xmlData, null, function() {
       xhrCount--;
       if (xhrCount === 0) {
           location.href = 'myurl'
       }
   });      
<?php endforeach; ?>  
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • It seems like the code is breaking. I added an alert to trace the loops. var xhrCount = ; var xmlData = 'Ths is the ET API call'; $.post('ET url for API call'+xmlData, null, function() { xhrCount--; if (xhrCount === 0) { location.href = 'myurl' } }); – mkrisch Apr 05 '12 at 17:36
  • `count()` should work, what kind of variable is `$listNumbers`, You can't use ``, You have to call echo, `` What I suggested in simpler syntax that is equivalent to the echo statement. Make sure you test what `count($listNumbers)` returns in isolation – Ruan Mendes Apr 05 '12 at 17:40
  • It seems like the code is breaking. I added an alert to trace the loops after the foreach loop is initiated. I get the first result. Then it quits. It never makes it to the location href. I also added else location href onto the if (xhrCount ===0) to see if the code was making it that far. Any ideas? – mkrisch Apr 05 '12 at 17:42
  • Add debugging in each `$.post` callback so you know what the current value of `xhrCount` is. When you can't figure out what is going on, you have to step through the code and find what line is not behaving correctly, "then it quits" doesn't show that you've given it enough of a try debugging it. – Ruan Mendes Apr 05 '12 at 17:43
  • let me take another look. brb – mkrisch Apr 05 '12 at 17:49
  • The loop works fine. It's the seccess call back. Looking at that now. – mkrisch Apr 05 '12 at 18:04
  • @mkrisch: upvotes are appreciated, choosing a correct answer is required :) – Ruan Mendes Apr 05 '12 at 19:28
  • I don't have the reputation to do that yet. I'm 4 points short... but I will vote this up when I can. – mkrisch Apr 05 '12 at 19:33
1
$(document).ready(function() { }); // this is NOT the callback of the AJAX request

The above won't work, because it will be called immediately, because you are staying on the same page (which is already ready). AJAX calls are asynchronous so it won't wait until the request is finished.

You could either make the call async or use the success callback of the ajax request.

To better clarify:

The $(document).ready(function() {}); fires when the DOM is ready (i.e. kinda like the page is loaded and I'm ready for other stuff (e.g. attaching event listeners)) . What you want to do is use the callback of .post() like:

$.post('ajax/test.html', function(data) {
  // this only gets called when the ajax request is finished
});

But the real question remains: why are you using a PHP loop to build AJAX requests. That just makes no sense at all. You are still building the page using PHP so why don't you also add the content you want to get using AJAX?

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • The OP wants to call `location.href`, that will cancel the XHRs if they aren't finished – Ruan Mendes Apr 05 '12 at 15:42
  • Yeah. So that's why the XHR calls should either be async or the `location.href` should be in the success callback. What's wrong with what I say above? Either I misunderstand you or you don't get me. – PeeHaa Apr 05 '12 at 15:47
  • The callback you are mentioning is for when the document is ready, not for when a `$.post` is finished. – Ruan Mendes Apr 05 '12 at 15:48
  • No I mean tthe callback of the AJAX function as stated. *NOT* the document ready, because as I state in my answer this won't work. – PeeHaa Apr 05 '12 at 15:49
  • I see, your `$.ready` code is very prominent, made me think that you were suggesting that is the callback to use, upvoted to offset my previous donwvote, but this answer still doesn't explain how to do it. There are multiple callbacks being called, you need to track that all of them are finished – Ruan Mendes Apr 05 '12 at 15:51
  • I tried to emphasize by starting with an arrow up pointing to the code and saying it doesn't work. But doing a good arrow up in markdown is hard :) – PeeHaa Apr 05 '12 at 15:53
  • I've found that adding a timer and then calling the location href works but it's kind of a hack. – mkrisch Apr 05 '12 at 15:58
  • @mkrisch what if someone is on a dialup? – PeeHaa Apr 05 '12 at 16:02
0

You could try this var jqxhr = $.post('ET url for API call'+xmlData);

After the loop:

jqxhr.complete(function(){
  location.href = "thank you url";
});

You can read about jqXHR status functions in the documentation.

But you may want to change your whole approach. Maybe your PHP should output one javascript array that your page could loop. What are you trying to accomplish?

Alex L
  • 8,419
  • 6
  • 43
  • 51
  • I'll give the abouve code a try. Stand by for confirmation... and thank you very much for helping! – mkrisch Apr 05 '12 at 15:59
  • @mkrisch This doesn't address the fact that there are multiple `$.post`s being called and you need to wait for all of them to finish. See my answer – Ruan Mendes Apr 05 '12 at 16:03
  • Hi Juan.. I'm using your code. I've got it working... mostly. I had to change var xhrCount = = count($listNumbers) ?>; to var xhrCount = ; The loops run, the results show up in Exact Target but the location href isn't working. I get a blank page. I'm troubleshooting now. – mkrisch Apr 05 '12 at 17:02
  • correction it works when I change xhrCount = = count($listNumbers) ?>; to xhrCount = 2; hard code. The count function isn't working. Could be my version of php. – mkrisch Apr 05 '12 at 17:06