Liga
Liga

Reputation: 3439

Getting undefined when using public class property

This is truly strange and I cannot understand why this is happening. When I call the startRecording() method it works perfectly and I can test that this.rec has been set. But then when I call stopRecording() method it says that this.rec is undefined. How can this be if I know that it is defined?

The problem is in RecorderClass.js when I call the stopRecording() method.

index.html

<html>
    <body>
        <div>
            <button id="recordButton">Record</button>
            <button id="stopButton">Stop</button>
        </div>

        <script src="recorder.js"></script>
        <script type="module" src="app.js"></script>
    </body>
</html>

app.js

import RecorderClass from './RecorderClass.js'

let recordButton = document.getElementById("recordButton")
let stopButton = document.getElementById("stopButton")

let RecorderObject = new RecorderClass()

recordButton.addEventListener("click", RecorderObject.startRecording)
stopButton.addEventListener("click", RecorderObject.stopRecording)

RecorderClass.js

class RecorderClass
{
    startRecording()
    {
        this.AudioContext = window.AudioContext || window.webkitAudioContext

        let constraints = { audio: true, video: false }

        navigator.mediaDevices.getUserMedia(constraints).then(stream => {
            let audioContext    = new AudioContext()
            this.gumStream       = stream
            let input           = audioContext.createMediaStreamSource(stream)
            this.rec             = new Recorder(input, { numChannels: 1 })
            this.rec.record()
        })

        // Returns an object !!!!!
        setTimeout(() => {
            console.log(this.rec)
        }, 3000)
    }

    stopRecording()
    {
        // Returns undefined !!!!!
        console.log(this.rec)

        this.rec.stop()
        this.gumStream.getAudioTracks()[0].stop()
    }
}

export default RecorderClass

Here is the project on CodePen (you can see the error in console)

https://codepen.io/martinszeltins/project/editor/ZBWJoN

Upvotes: 0

Views: 119

Answers (1)

trincot
trincot

Reputation: 350290

You are losing the this reference here:

recordButton.addEventListener("click", RecorderObject.startRecording)
stopButton.addEventListener("click", RecorderObject.stopRecording)

You pass the function reference as callback to addEventListener. When the event happens, that callback is called without any particular this binding.

You should instead do:

recordButton.addEventListener("click", () => RecorderObject.startRecording())
stopButton.addEventListener("click", () => RecorderObject.stopRecording())

Now these methods are called on your object, which serves as this during the call.

NB: it would be good to name your instance objects with an initial lowercase letter, as initial capitals are commonly used for constructors/classes.

Upvotes: 2

Related Questions