Angular and Three.js: Why does my click event is not firing?

Hello everyone,

I’m working on an Angular project and have created a shelf with clickable element represented by a simple cube. However in a later version, I want to display a specific .gltf element on the shelf and also have a click event on it. Unfortunately, the click event already doesn’t seem to be working on the Mesh when I use either “click” or “pointerdown”. The alert message is not displayed and there are no errors in the console. Here is the code for the component:

import {
  AfterViewInit,
  Component,
  ElementRef,
  Input,
  OnInit,
  ViewChild,
} from '@angular/core';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

@Component({
  selector: 'app-visualiation-magazin',
  templateUrl: './visualiation-magazin.component.html',
  styleUrls: ['./visualiation-magazin.component.scss'],
})
export class VisualiationMagazinComponent implements OnInit, AfterViewInit {
  constructor() {}
  @ViewChild('canvas') public canvasRef!: ElementRef;

  @Input()
  public cameraZ: number = 400;

  @Input()
  public fieldOfView: number = 20;

  @Input('nearClipping')
  public nearClippingPlane: number = 1;

  @Input('farClipping')
  public farClippingPlane: number = 1000;

  private camera!: THREE.PerspectiveCamera;

  private get canvas(): HTMLCanvasElement {
    return this.canvasRef.nativeElement;
  }

  private renderer!: THREE.WebGLRenderer;
  private scene!: THREE.Scene;

  private cube!: THREE.Mesh;

  public ngOnInit(): void {}

  private createCube(): void {
    console.log('create cube');
    const cubePosition = new THREE.Vector3(-0.15, 0.42, 0);

    // Create the cube and set its position
    const cubeGeometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);

    const cubeMaterial = new THREE.MeshBasicMaterial({
      color: 0xffffff,
    });
    this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    this.cube.addEventListener('pointerdown', () => {
      alert('click2');
    });
    this.cube.position.copy(cubePosition);
  }

  private createScene() {
    this.scene = new THREE.Scene();
    const loader = new GLTFLoader();
    this.createCube();

    loader.load(
      '/assets/scene.gltf',
      (gltf: any) => {
        this.scene.add(this.cube);
        this.scene.add(gltf.scene);

        /**
         * PLACE cube START
         */

        // Access the glTF object in the scene
        const gltfObject = gltf.scene;

        // Find the position where you want to place the cube
        // Add the cube to the glTF object's children
        //gltfObject.add(this.cube);

        /**
         * PLACE cube END
         */
        const axesHelper = new THREE.AxesHelper(5);
        this.scene.add(axesHelper);

        this.startRenderingLoop();
      },
      function (xhr) {
        console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
      },
      (error: any) => {
        console.error(error);
      }
    );

    this.scene.background = new THREE.Color(0xadd8e6);
    //this.scene.add(this.cube);

    const aspectRatio = this.getAspectRatio();
    this.camera = new THREE.PerspectiveCamera(
      this.fieldOfView,
      aspectRatio,
      this.nearClippingPlane,
      this.farClippingPlane
    );
    this.camera.position.z = this.cameraZ;

    const controls = new OrbitControls(
      this.camera,
      this.canvasRef.nativeElement
    );
    controls.minDistance = 2;
    controls.maxDistance = 10;
    controls.target.set(0, 0, -0.2);
    controls.update();
  }
  private getAspectRatio() {
    return this.canvas.clientWidth / this.canvas.clientHeight;
  }

  private startRenderingLoop() {
    console.log('akldfjklasjdfklas');
    this.renderer = new THREE.WebGLRenderer({
      canvas: this.canvas,
      antialias: true,
    });
    this.renderer.setPixelRatio(devicePixelRatio);
    this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);

    this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
    this.renderer.toneMappingExposure = 1;
    let component: VisualiationMagazinComponent = this;
    (function render() {
      requestAnimationFrame(render);
      //component.animateCube();

      component.renderer.render(component.scene, component.camera);
    })();
  }
  public ngAfterViewInit(): void {
    this.createScene();
    this.startRenderingLoop();
  }
}

Any suggestions on how to make the click event work or what I might be doing wrong would be greatly appreciated. Thank you in advance!

In my experience, addEventListener can only be used for DOM elements.
I would take a look at the Raycaster of Three.js. Maybe this will help you, there is also an example to try out: three.js docs