Search code examples
javascriptjquerycallbackcoffeescriptscoping

Scoping issue when attempting to call CoffeeScript method inside Fancybox callback


I have the following CoffeeScript module named Course. I have a small piece of code which I would like to re-use, I have created a method called preSelectItemSize.

I would like to call this method when init is called and also within the afterShow Fancybox callback. The following code works, but it don't believe it is correct to use the module name and I should be using the @ reference to "this" instead.

What am I doing wrong? (Code snippet reduced for brevity)

$ = window.jQuery = require("jquery")
Course =

  init: ->

    $('.js-product-overlay').on 'click', (e) =>
      @viewProductClickHandler(e, MediaDetection)

    @preSelectItemSize()

  viewProductClickHandler: (e, mediaDetection) =>

    $('.js-product-overlay').fancybox({
      href: wishlist_overlay_href
      maxWidth: '775px'
      minHeight: '495px'
      autoCenter: '!isTouch'
      height: 'auto'
      scrolling: true
      fitToView: false
      autoSize: false
      padding: 0
      tpl:
        closeBtn: '<a class="fancybox-item modal__close fancybox-close" href="javascript:;">Close</a>'
      afterShow: ->
        $('.js-fancybox-close').on 'click', (e) ->
          e.preventDefault()
          $.fancybox.close()

        Course.preSelectItemSize()
    })

  preSelectItemSize: ->
    itemId = $('.modal__product-info').attr('data-item-id')
    $('#size-' + itemId).click()

module.exports = Course

Solution

  • The following works by changing the viewProductClickHandler to a thin arrow and changing the afterShow callback to a fat arrow:

    Course =
    
      init: ->
    
        $('.js-product-overlay').on 'click', (e) =>
          @viewProductClickHandler(e, MediaDetection)
    
        @preSelectItemSize()
    
      viewProductClickHandler: (e, mediaDetection) ->
    
        $('.js-product-overlay').fancybox({
          href: wishlist_overlay_href
          maxWidth: '775px'
          minHeight: '495px'
          autoCenter: '!isTouch'
          height: 'auto'
          scrolling: true
          fitToView: false
          autoSize: false
          padding: 0
          tpl:
            closeBtn: '<a class="fancybox-item modal__close fancybox-close" href="javascript:;">Close</a>'
          afterShow: =>
            $('.js-fancybox-close').on 'click', (e) ->
              e.preventDefault()
              $.fancybox.close()
    
            @preSelectItemSize()
        })
    
      preSelectItemSize: ->
        alert "preSelectItemSize executed."
        itemId = $('.modal__product-info').attr('data-item-id')
        $("#size-#{itemId}").click()
    
    Course.init()
    

    See fiddle for example of working code: https://jsfiddle.net/L5u31Lzr/1/