vendredi 30 novembre 2018

Jasmine/Javascript - why is a DOM element only accessible by reference from within an async then()?

After a loooot of testing... I stumbled upon some interesting behavior that I don't understand.

Code:

function someFunction() {
  ... // whatever this is stubbed
}

// below is called ("mounted") by finalDOM.mountUserActions()     
$("#button").click(function() {
  savedElement = $("#saved_element")
  console.log("BEFPRE THEN in event listener ==========")
  console.log("found saved_element? = " + savedElement.length)
  console.log("found unsaved_element? = " + $("#unsaved_element").length)

  someFunction().then(function(result){
    savedElement.val(result)
    $("#unsaved_element").val(result)
    console.log("INSIDE THEN in event listener ==========")
    console.log("found saved_element? = " + savedElement.length)
    console.log("found unsaved_element?  = " + $("#unsaved_element").length)
  })
})

Test code:

fdescribe("on click of button", function() {
  beforeEach(function(){
    response = Promise.resolve("test")
    spyOn(window, "someFunction").and.returnValue(response)
    savedElement = affix("#saved_element")
    affix("#unsaved_element")
    affix("#button")
    finalDOM.mountUserActions();
    $("#button").click()
  })
  it("should change value of saved_element", function() {
    response.then(function() {
        console.log("INSIDE SPEC EXPECTATION ==========")
        console.log("value of saved_element = " + savedElement.val())
        console.log("value of unsaved_element = " + $("#unsaved_element").val())
      expect(savedElement.val()).toEqual("test") // PASS
      expect($("#unsaved_element").val()).toEqual("test") // FAIL
    })
  })
})

Console output:

BEFPRE THEN in event listener ==========
found saved_element? = 1
found unsaved_element? = 1
INSIDE THEN in event listener ==========
found saved_element? = 1
found unsaved_element?  = 0
INSIDE SPEC EXPECTATION ==========
value of saved_element = test
value of unsaved_element = undefined

The fact that the length of both elements are 1 in BEFORE THEN in event listener proves that the affix worked, both elements are on the page, so then why is only the saved element found once INSIDE THEN in event listener?

I don't think I've ever encountered this... is this a Javascript gotcha or a Jasmine one? Would love to learn more about it to avoid this in the future... have spent a lot of time scratching my head on it.

Aucun commentaire:

Enregistrer un commentaire