Three.js r89: runtime error THREE.JSONLoader is not a constructor [blueprint3d]

Hello everyone!

I am currently in the process of reviving an old Three.js TypeScript project within Docker.

Currently, I can successfully compile the TypeScript files without errors and serve everything using Python’s http.server. However, I encounter a runtime error: THREE.JSONLoader is not a constructor.

This is the scene.ts file where the error happens:

/// <reference path="../core/utils.ts" />
/// <reference path="../items/factory.ts" />

module BP3D.Model {

  export class Scene {

    private scene: THREE.Scene;
    private items: Items.Item[] = [];
    public needsUpdate = false;
    private loader: THREE.JSONLoader;
    private textureLoader: THREE.TextureLoader;
    private itemLoadingCallbacks = $.Callbacks();
    private itemLoadedCallbacks = $.Callbacks();
    private itemRemovedCallbacks = $.Callbacks();

    constructor(private model: Model, private textureDir: string) {
      this.scene = new THREE.Scene();

      // error here:  THREE.JSONLoader is not a constructor
      this.loader = new THREE.JSONLoader();
      this.loader.crossOrigin = "";

      this.textureLoader = new THREE.TextureLoader();
      this.textureLoader.setCrossOrigin("");

    }

    public add(mesh: THREE.Mesh) {
      this.scene.add(mesh);
    }

    public remove(mesh: THREE.Mesh) {
      this.scene.remove(mesh);
      Core.Utils.removeValue(this.items, mesh);
    }

    public getScene(): THREE.Scene {
      return this.scene;
    }

    public getItems(): Items.Item[] {
      return this.items;
    }

    public itemCount(): number {
      return this.items.length
    }

    public clearItems() {
      var items_copy = this.items
      var scope = this;
      this.items.forEach((item) => {
        scope.removeItem(item, true);
      });
      this.items = []
    }

    public removeItem(item: Items.Item, dontRemove?: boolean) {
      dontRemove = dontRemove || false;
      this.itemRemovedCallbacks.fire(item);
      item.removed();
      this.scene.remove(item);
      if (!dontRemove) {
        Core.Utils.removeValue(this.items, item);
      }
    }

    public addItem(itemType: number, fileName: string, metadata, position: THREE.Vector3, rotation: number, scale: THREE.Vector3, fixed: boolean) {
      itemType = itemType || 1;
      var scope = this;
      var loaderCallback = function (geometry: THREE.Geometry, materials: THREE.Material[]) {
        var item = new (Items.Factory.getClass(itemType))(
          scope.model,
          metadata, geometry,
          new THREE.MultiMaterial(materials),
          position, rotation, scale
        );
        item.fixed = fixed || false;
        scope.items.push(item);
        scope.add(item);
        item.initObject();
        scope.itemLoadedCallbacks.fire(item);
      }

      this.itemLoadingCallbacks.fire();
      this.loader.load(
        fileName,
        loaderCallback,
        undefined
      );
    }
  }
}

I am aware that THREE.JSONLoader was removed with r99 from the core, and removed completely with r111 . I also acknowledge that the recommendation is to switch to a glTF-based workflow.

However, before undertaking such a task, I aim to have a working version of this legacy project up and running before I proceed with updates from that point onwards.

Therefore my question is explicitly how to solve the runtime error THREE.JSONLoader is not a constructor on older versions of Three.js (the version the project uses is r89).

I would greatly appreciate any insights or hints that could help me solve this problem and breathe new life into this fantastic project. Thank you very much!

It was moved to deprecated directory. And in future versions replaced by ObjectLoader iirc.

Hello @mjurczyk,

thanks for your answer. Actually the project that I am trying to revive uses Three.js r89, as specified in the package.json file (snippet shown here):

 "dependencies": {
    "@types/jquery": "^3.3.0",
    "@types/three": "0.89.4",
    "bootstrap": "^3.3.1",
    "bootstrap-tour": "^0.10.1",
    "inherits": "^2.0.1",
    "jquery": "^2.1.3",
    "polygon": "^0.1.0",
    "segseg": "^0.2.1",
    "three": "0.89.0",
    "underscore": "^1.7.0",
    "vec2": "^1.6.0"
  },

In Three.js r89 THREE.JSONLoader should still be accessible. Based on a similar questions that I found (javascript - THREE.FileLoader is not a constructor(…) - Stack Overflow) I suspect there might be an issue with how I’m importing the class, but I’m struggling to pinpoint what needs to be changed.

PS: just edited my original question a bit to be clearer on my objective.