Search code examples
javascriptajaxcoffeescriptlong-polling

Call a function inside Ajax


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.


Solution

  • 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.