The PointerLockControls.js file encountered an error: it cannot read properties of undefined, specifically trying to read 'lock' at an HTMLDivElement

As a newcomer to Javascript and Three.js, I'm seeking guidance on implementing a first-person camera using three.js. I'm trying to convert the PointerLockControls.js example found here: PointerLockControls example

The problem arises when I encounter the error 'TypeError: Cannot read properties of undefined (reading 'lock') at HTMLDivElement.', specifically caused by line 204 in my code:

 // initialise locks: 
    const blocker = document.getElementById( 'blocker' );
    const instructions = document.getElementById( 'instructions' );
        
    instructions.addEventListener( 'click', function () {
        // LINE 204: ERROR
        this.controls_.lock;
    } );

In the example provided, the lock function is defined as:

instructions.addEventListener( 'click', function () {

                    controls.lock();

                } );

I understand that the issue stems from `this.controls_` being undefined at runtime. Even though I create and assign `this.controls_` before adding the event listener, it appears to be undefined when 'this.controls_.lock' is called.

Could it be that `this.controls_` needs to be defined independently of the event listener for it to work within the listener scope?

Prior attempts involved defining:

instructions.addEventListener( 'click', function () {
            this.controls_.lock();
        } );

where `PointerCamera.lock` was implemented as:

lock() {
       this.controls.lock();
}

I've experimented with redefining my lock functions using `const = function () {...}` which led to a type error in the PointerLockControls.js file.

Any insights or assistance on addressing this matter would be highly valued!

Full Javascript code snippet:

import * as THREE from '../three.js-r134/three.js-r134/build/three.module.js';
import { FirstPersonControls } from '../three.js-r134/three.js-r134/examples/jsm/controls/FirstPersonControls.js';
import { PointerLockControls } from '../three.js-r134/three.js-r134/examples/jsm/controls/PointerLockControls.js';

// Your complete JavaScript implementation goes here...

And here's a snippet of the corresponding HTML:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Trying to get basic FPS control</title>
        <style>
           /* CSS styling for your HTML content */
        </style>
    </head>
    <body>
        <div id="blocker">
            <div id="instructions">
                <p style="font-size:36px">
                    Click to play
                </p>
                <p>
                    Move: WASD<br/>
                    Jump: SPACE<br/>
                    Look: MOUSE
                </p>
            </div>
        </div>
        <script type="module" src="./fpsbasic.js"></script>
    </body>
</html>

Answer №1

To ensure that each call has the appropriate scope to execute FirstPersonCameraDemo.controls_ and PointerCamera.controls correctly, it was necessary to properly bind the correct this to each of the new lock functions.

The insight shared in a discussion about the scope of handler functions in addEventListener was instrumental in understanding that the event handler functions wouldn't have access to the classes' correct 'this', but instead would refer to instructions.

The revised definitions are:

within FirstPersonCameraDemo:

instructions.addEventListener( 'click', this.controls_.lock2().bind(this));

Within 'PointerCamera':

    initControls() {
        this.controls = new PointerLockControls(this.camera, this.dElement);

        // locks
        this.lock = function (e) {
            return this.controls.lock(e);
        }

        this.unlock = function () {
            this.controls.unlock();
        }
    }

    lock2() {return this.lock.bind(this)}
    unlock2() {return this.unlock.bind(this)}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

saving selected values to the database

I have updated the question, thank you for your help. The code seems to be working fine but I need some assistance with increasing the booked count in the database when the user clicks "Confirm Choices." Additionally, if the user selects a booked image, ...

Ways to enhance radio imagery selection?

I'm just starting out with JS and could really use some guidance on how to improve my code. I think it might need a single function for all options, but I'm not sure. It's working fine right now, but I have a feeling it could be better ;) H ...

The meshes in my Unity game appear flipped after I import them from 3ds Max with skinning applied

After bringing my meshes from 3ds MAX to Unity with skinning, I've noticed that they appear inverted in-game. Both the mesh and normals seem to be reversed, giving them an eerie, ghost-like appearance. Interestingly, disabling the skin option resolv ...

Shutting down a filtered v-treeview node becomes sluggish when operating with a large number of items

My v-treeview has a node with approximately 2000 children, and I am in need of applying a filter to it. However, the current issue is that opening the node takes around 3 seconds, while closing it takes about 15 seconds, which is completely unacceptable. ...

Passing parameters as an array in Angular can be done by using the format: ?category[]=1&category[]=2&category[]=3,

Struggling to send an array using the $http.get() method in AngularJS. Here's my current approach: $http.get('/events.json', {params: {category_id: [1,2]}}); While I anticipate the request to be sent as /events.json?category_id[]=1&cat ...

What is the best way to redirect a user to a different URL in Express while also sending additional data along with the request

[NODE, express] Developing a Facebook application where user grants access and is redirected to my site with a unique code at abc.com/heyBuddy/fb/callback?code="adasdasdasda". Once the code is received in route router.get('/heyBuddy/fb/callback', ...

Tips for utilizing the getJson method to pass a variable to a PHP file

I need help with my JavaScript code, as I am trying to pass a datastring containing the value "no" to data.php using getJson in order to receive JSON as a response. However, my JavaScript code is not functioning correctly. Below is the code that I have: J ...

Session-based Authorization

I'm completely new to working with express.js, and I've been facing an issue while trying to create a session-cookie after logging in. Even though I can initiate the session and successfully log in, the session data doesn't carry over to the ...

My React setup is causing some problems that I need to address

React is not my strong suit, but I need to test a React application. The issue arises when attempting to run the server using gulp nodemon, resulting in numerous errors. It seems that the application is built on an outdated version of React and some libra ...

Steps for resetting the counter to 0 following an Ajax Refresh or Submission to the database

I have been working on a code that successfully sends multiple data to a MySQL Database using JQuery Ajax. Everything works smoothly, but I encountered an issue when trying to refresh the page with ajax and add a new record; it populates the number of time ...

Initialize React Native project

Which ruby command shows the path to Ruby: /Users/User/.rbenv/shims/ruby Ruby -v command displays the version of Ruby installed: ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin21] Which bundle command reveals the path to Bundler: /Users/Us ...

Utilizing CSS to set a map as the background or projecting an equirectangular map in the backdrop

How can I set an equirectangular projection like the one in this example http://bl.ocks.org/mbostock/3757119 as a background for only the chart above the X-axis? Alternatively, is it possible to use an image of a map as a CSS background instead? .grid . ...

Are you on the lookout for an Angular2 visual form editor or a robust form engine that allows you to effortlessly create forms using a GUI, generator, or centralized configuration

In our development team, we are currently diving into several Angular2< projects. While my colleagues are comfortable coding large forms directly with Typescript and HTML in our Angular 2< projects, I am not completely satisfied with this method. We ...

Elevate the element from the choice API to the organization API using this.$parent

I recently developed a Vue 3 component called "Tab" using the option API. Here is the code: export default { name: "Tab", props: { name: {required: true}, iconClass: {required: true}, selected: {default: false} }, da ...

The absence of a backslash in the JSON string is noticed upon uploading it to the database

After using the JSON.stringify() method in JavaScript to convert my JSON object into a JSON string, I insert it into a database via AJAX posting to a PHP file. $("#saveToDatabase").click(function(){ var place = searchBox.getPlaces(); var locati ...

Ways to extract the variable value from two asynchronous functions

I need to create a script that generates live currency conversion rates for a given array of currencies. For example, if the array is ['USD','AUD','GBP'], I want the script to calculate conversions like USD->AUD, USD->GB ...

Is NodeJS primarily used as a socket library for network communication?

Here is a server program written in C language using socket functionality provided by libC # include <unistd.h> # include <sys/socket.h> # include <sys/types.h> # include <string.h> #include <netinet/in.h> main(){ int listfd ...

Updating mesh matrix in React three fiber after rotating parent group

Greetings for taking the time to review my question. I am currently using Threejs in combination with react-three-fiber. My goal is to attach small boxes to both sides of a mesh. To achieve this, I am getting the position for the box mesh from the raycast ...

Having trouble sending the request body via next-http-proxy-middleware

Recently, I've been attempting to develop a frontend using nextjs that communicates with a Java backend. To achieve this, I'm utilizing the npm package next-http-proxy-middleware. However, it seems like either my request body is getting lost in t ...

Express.Js having identical parameter names that are not being passed

I'm currently experiencing an issue with Express.Js. When I visit /article/14, the parameters returned are: { artId: '14' } { artId: 'img' } I'm puzzled about the presence of the img part and why the value is repeated. Strang ...