Search code examples
javascriptobjectsetter

Object setter UNDEFINED in JS


My first try to build an OO example with pure JS. MyInput groups three HTML Elemnts together. Initializing it with new MyInput('sometext') works as expected, but not inp = new MyInput(); inp.header = 'other text'.

I tried to create a setter method but this fails saying this.h2 undefined.

const root = document.querySelector('#root')

const h1 = document.createElement('h1')
h1.textContent = 'Just Testing'
root.appendChild(h1)

// guess = Math.floor( Math.random() * 100)
// document.title = guess

class MyInput {

    constructor(header) {
        
        this.header = header

        const h2 = document.createElement('h2')
        h2.textContent = this.header
        this.h2 = h2
        
        this.div = document.createElement('div')

        const inp = document.createElement('input')
        inp.disabled = true

        inp.addEventListener('blur',
                             (e)=>{
                                 inp.disabled = true
                                 but.style.visibility = 'visible'
                             }
                            )
        
        const but = document.createElement('button')
        but.textContent = 'unlock'
        but.addEventListener('click',
                             ()=>{
                                 but.style.visibility = 'hidden'
                                 inp.disabled = false
                                 inp.focus()
                             })

        this.div.appendChild(h2)
        this.div.appendChild(inp)
        this.div.appendChild(but)
    }
    // following line throws error this.h2 undefined
    set header (newHeader) {this.h2.textContent = newHeader} // ???

}

const i1 = new MyInput('this works')
root.appendChild(i1.div)

const i2 = new MyInput()
i2.header = 'this does not work?!?'
root.appendChild(i2.div)
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
  </head>
  <body>
    <div id='root'></div>
    <script src='test.js'></script>
  </body>
</html>


Solution

  • Simply moving the critical line this.header = header after this.h2 = h2 did it!

    console.log('yo!')
    
    document.title = 'hello world'
    
    const root = document.querySelector('#root')
    
    const h1 = document.createElement('h1')
    h1.textContent = 'Just Testing'
    root.appendChild(h1)
    
    class MyInput {
    
        constructor(header) {
    
            const h2 = document.createElement('h2')
            h2.textContent = header
            this.h2 = h2
            this.header = header // <- this line moved
            this.div = document.createElement('div')
    
            const inp = document.createElement('input')
            inp.disabled = true
    
            inp.addEventListener('blur',
                                 (e)=>{
                                     inp.disabled = true
                                     but.style.visibility = 'visible'
                                 }
                                )
            
            const but = document.createElement('button')
            but.textContent = 'unlock'
            but.addEventListener('click',
                                 ()=>{
                                     but.style.visibility = 'hidden'
                                     inp.disabled = false
                                     inp.focus()
                                 })
    
            this.div.appendChild(h2)
            this.div.appendChild(inp)
            this.div.appendChild(but)
        }
    
        set header (newHeader) {this.h2.textContent = newHeader}
    
    }
    
    const i1 = new MyInput('this works')
    root.appendChild(i1.div)
    
    const i2 = new MyInput()
    i2.header = 'and now this also works!'
    root.appendChild(i2.div)
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset='utf-8'>
      </head>
      <body>
        <div id='root'></div>
        <script src='test.js'></script>
      </body>
    </html>