Orbit Controls troubles with OBJ Loader in Angular 8

Hello, I am having some trouble loading my obj object with OBJLoader from threejs in Angular 8, the error is:
ERROR TypeError: three_orbit_controls__WEBPACK_IMPORTED_MODULE_2__.OrbitControls is not a constructor
at ThreeComponent.play3D (three.component.ts:77)

this is my code:

import { Component, ElementRef, Input, ViewChild } from '@angular/core';
import * as THREE from 'three';
import { OrbitControls } from 'three-orbit-controls';
// import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';

@Component({
  selector: 'app-three',
  templateUrl: './three.component.html',
  styleUrls: ['./three.component.scss'],
})
export class ThreeComponent {
  @ViewChild('rendererContainer') rendererContainer: ElementRef;
  @Input() threeDPath: string;
  @Input() darkMode: boolean;

  loaderType: string; // OBJ | 3MF

  nativeElement: any;
  comp: any;
  object: any;

  renderer: any;
  camera: any;
  scene: any;
  controls: any;

  constructor(el: ElementRef) {
    this.nativeElement = el.nativeElement;
    setTimeout(() => {
      this.loaderType = this.threeDPath.substr(this.threeDPath.lastIndexOf('.') + 1);
      this.play3D();
      this.animate();
    });
    this.render = this.render.bind(this);
    this.onWindowResize = this.onWindowResize.bind(this);
    this.onProgress = this.onProgress.bind(this);
    this.animate = this.animate.bind(this);

    this.darkMode = true;
  }

  animate() {
    requestAnimationFrame(this.animate);
    this.render();
  }
  play3D() {
    const domElement = this.nativeElement.children[0];
    domElement.innerHTML = '';
    this.renderer = new THREE.WebGLRenderer({
      antialias: true,
      preserveDrawingBuffer: true,
    });
    this.renderer.setPixelRatio(window.devicePixelRatio);
    // this.renderer.setSize(domElement.offsetWidth, domElement.offsetWidth / window.devicePixelRatio);
    this.renderer.setSize(domElement.offsetWidth, domElement.offsetHeight);

    domElement.appendChild(this.renderer.domElement);

    this.scene = new THREE.Scene();
    if (this.darkMode) {
      this.scene.background = new THREE.Color(0x000000);
    } else {
      this.scene.background = new THREE.Color(0xffffff);
    }
    this.scene.add(new THREE.AmbientLight(0xcccccc, 0.4));
    this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
    // this.camera.position.set(-2, 2, 2); // z - to control if this is too small

    // this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
    // this.camera.position.set(-2, 2, 250);

    this.camera.add(new THREE.PointLight(0xffffff, 0.8));

    this.scene.add(this.camera);

    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    const loader = new OBJLoader();
    // const loader = new FBXLoader();

    loader.load(
      this.threeDPath,
      (obj) => {
        // center asset
        // const box = new THREE.Box3().setFromObject(obj);
        // const center = new THREE.Vector3();
        // box.getCenter(center);
        // obj.position.sub(center);
        // this.scene.add(obj);

        const box = new THREE.Box3().setFromObject(obj);
        const size = box.getSize(new THREE.Vector3()).length();
        const center = box.getCenter(new THREE.Vector3());
        this.controls.reset();

        obj.position.x += obj.position.x - center.x;
        obj.position.y += obj.position.y - center.y;
        obj.position.z += obj.position.z - center.z;
        this.controls.maxDistance = size * 10;
        this.camera.near = size / 100;
        this.camera.far = size * 100;
        this.camera.updateProjectionMatrix();

        this.camera.position.copy(center);
        this.camera.position.x += size / 2.0;
        this.camera.position.y += size / 5.0;
        this.camera.position.z += size / 2.0;

        this.camera.lookAt(center);
        this.scene.add(obj);
        this.controls.update();
      },
      this.onProgress,
    );

    window.addEventListener('resize', this.onWindowResize, false);
  }
  onProgress(xhr) {
    if (xhr.lengthComputable) {
      const percentComplete = (xhr.loaded / xhr.total) * 100;
      console.log('model ' + percentComplete + '% downloaded');
    }
  }

  onWindowResize() {
    const domElement = this.nativeElement.children[0];
    this.camera.aspect = domElement.offsetWidth / domElement.offsetHeight;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(domElement.offsetWidth, domElement.offsetHeight);
  }
  render() {
    this.renderer.render(this.scene, this.camera);
  }
}

Instead of importing OrbitControls from three-orbit-controls, please import it from the three package like so:

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
1 Like

OH great it works!
Thank you very much!

1 Like