0

I'm having a problem, I can't make a loop inside this code:

    class ProductsPager
      constructor: ->
        this.waitformsg()
      waitformsg: =>
        alert 'begin'
        $.ajax
          type: "GET"
          url: "http://0.0.0.0:3000/live/index.json"
          async: true
          cache: false
          timeout: 1000
          success: (data) ->
            alert data
          error: (XMLHttpRequest, textStatus, errorThrown) ->
            alert "end"
            waitformsg()setTimeout "waitformsg()", 0

The two arlerts are for debugging. It displays me only one time of each: "begin", and right after "end" and nothing else.
I have concluded that the last line is wrong and I need to find a way to call a method inside Ajax.
I have tried to replace setTimeout "waitformsg()", 0 by this.waitformsg() or even waitformsg() but it still doesn't work.

I would like to display infinite "alerts" untill the right conditions to succeed are gathered.

Dariush Jafari
  • 5,223
  • 7
  • 42
  • 71
sidney
  • 2,704
  • 3
  • 28
  • 44

2 Answers2

1

These two:

waitformsg()
setTimeout waitformsg, 0

won't work because there is no waitformsg function in scope.

This:

setTimeout "waitformsg()", 0

won't work because there is no global function called waitformsg, the string form of setTimeout executes the string in the global context. I'd recommend that you forget that setTimeout even has a string form.

You should bind the callbacks to the current context using a fat arrow (=>):

waitformsg: =>
  alert 'begin'
  $.ajax
    #...
    error: (XMLHttpRequest, textStatus, errorThrown) =>
      alert "end"
      @waitformsg()

And if you want the error handler to wait a second before trying again:

setTimeout @waitformsg, 1000

The waitformsg method will run in the correct context because you defined it as a bound function.

A couple more things while I'm here:

  1. Using @ is more idiomatic in CoffeeScript than using this so your constructor should be:

    constructor: ->
      @waitformsg()
    
  2. jQuery's async:true flag for $.ajax has been deprecated so you should stop using it. async:true is also a nasty thing to do to your users (especially in a loop) so again, you should stop using it.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
0

I haven't played with CoffeeScript much, so here's how you would do it in Javascript:

waitformsg: function() {
    var self = this;

    ...
    ...

    error: function(XMLHttpRequest, textStatus, errorThrown) {
        self.waitformsg();
    };
};

When you simply call waitformsg(), you're basically calling window.waitformsg(). Since this doesn't exist, your code doesn't work. You cannot use this, because the callback is asynchronous and so the value of this is pretty much whatever jQuery sets it to (if it sets it at all) when the error callback is called. So you need to maintain a reference to this that gets passed down into the close as well and you can do this by creating a new variable in the local scope of the function and assigning this to that variable (in this case, I've called that new variable self). Then you can call self.waitformsg();.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295