Ty Everett
Ty Everett

Reputation: 59

NodeJS: Cannot read property 'hide' of undefined

The Problem

I'm working with Electron and Node, and am having issues where a variable (this.mainWindow) is only accessible inside of the function it was created in. Whenever an event listener fires, this.mainWindow is undefined. This is all occurring inside of a class, so this should be a reference to the working instance of that class, correct?

The Code

class AppManager {

    constructor (app, options) {
        this.app = app
        this.options = options = {}
        this.bindEvents()
    }

    bindEvents () {
        this.app.on('ready', this.onReady.bind(this))
        this.app.on('window-all-closed', this.onWindowAllClosed.bind(this))
        this.app.on('activate', this.onActivate.bind(this))
    }

    onReady () {
        this.createWindow()
    }

    onWindowAllClosed () {
        if (process.platform !== 'darwin') {
            this.app.quit()
        }
    }

    onActivate () {
        if (this.app.mainWindow === null) {
            this.createWindow()
        }
    }

    onClose (e) {
    // here, this.mainWindow and this.isQuitting are undefined.
        if (this.isQuiting) {
            this.mainWindow = null
        } else {
            e.preventDefault()
            this.mainWindow.hide()
        }
    }

    onClick () {
        // here, this.mainWindow is undefined.
        this.mainWindow.show()
    }

    createWindow () {
    // here, we declare this.isQuitting
        this.isQuitting = false

        this.contextMenu = Menu.buildFromTemplate([
            {
                label: 'Show App',
                click: function () {
                    this.mainWindow.show()
                }
            },
            {
                label: 'Quit',
                click: function () {
                    this.isQuiting = true
                    this.app.quit()
                }
            }
        ])

        this.tray = new Tray('./public/images/icon.ico')
        this.tray.setContextMenu(this.contextMenu)
        this.tray.on('click', this.onClick)

        // at this point, we assign the variable mainWindow to "this".
        this.mainWindow = new BrowserWindow(this.options)
        this.mainWindow.loadURL(url.format({
            pathname: path.join(__dirname, '../../../public/index.html'),
            protocol: 'file:',
            slashes: true
        }))
        this.mainWindow.tray = this.tray
        this.mainWindow.on('close', this.onClose)
    }
}

The Error

A JavaScript error occurred in the main process Uncaught exception: TypeError: cannot read property hide of undefined

The error occurs when I close the window, or click on the tray icon. That is when onClose and onClick fire, and that is when this.mainWindow and this.isQuitting are undefined

Let me know if you'd like more information.

Any thoughts or suggestions are appreciated :)

Upvotes: 0

Views: 1787

Answers (1)

Evert
Evert

Reputation: 99786

you are passing this.onClose, but you are probably losing the reference to this.

this.mainWindow.on('close', this.onClose.bind(this));

Should fix it.

Upvotes: 1

Related Questions