Odd error while using curves and points from JSON file

Hello,

I’m trying to create a simple curve, the points are from a JSON file, when testing the code this error is shown:

chunk-R3I2WUGT.js?v=b85cb02e:2486 Uncaught TypeError: Cannot read properties of undefined (reading 'x')
    at _Vector3.subVectors (chunk-R3I2WUGT.js?v=b85cb02e:2486:16)
    at CatmullRomCurve3.getPoint (chunk-R3I2WUGT.js?v=b85cb02e:20834:11)
    at CatmullRomCurve3.getPoints (chunk-R3I2WUGT.js?v=b85cb02e:20503:24)
    at MeshManager.initCurve (MeshManager.js?t=1702903561300:56:30)
    at main.js:29:13
initCurve	@	MeshManager.js?t=1702903561300:56
(anonymous)	@	main.js:29
Show 3 more frames

my code is as follow: (note this script is a class and defined in the main js)

initCurve() {

        const curvePoints = [];
        fetch("./src/curve.json").then((res) => { return res.json(); }).then((data) => {
            data.points.forEach(element => {
                curvePoints.push(new THREE.Vector3(element.x, element.y, element.z));
            });
        });
        console.log(curvePoints);

        const curve = new THREE.CatmullRomCurve3(curvePoints);
        const points = curve.getPoints(11);
        const geometry = new THREE.BufferGeometry().setFromPoints(points);
        const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
        const curveObject = new THREE.Line(geometry, material);

        this.scene.add(curveObject);
    }

The JSON decoding part is from the internet and I’m not 100% sure I understand the code fully, though if I log the array curvePoints it looks correct.
I manually typed this JSON file (I just copied the points from blender spreadsheet)

{
    "points": [
        { "x":0,     "z":2,      "y":0},
        { "x":1.286, "z":1.532,  "y":0.444},
        { "x":1.970, "z":0.347,  "y":0.889},
        { "x":1.732, "z":-1,     "y":1.333},
        { "x":0.684, "z":-1.879, "y":1.778},
        { "x":-0.684,"z":-1.879, "y":2.222},
        { "x":-1.732,"z":1,      "y":2.667},
        { "x":-1.970,"z":0.347,  "y":3.111},
        { "x":-1.286,"z":1.532,  "y":3.556},
        { "x":0,     "z":2,      "y":4}
    ]
}

The error is at curve.getPoints, if I just wrote a list of points as new THREE.CatmullRomCurve3([new THREE.Vector3(x,y,z), ...]) it work perfectly. The thing is now it’s a small number from points, I’m just testing later I’ll create large JSON files, what’s wrong with my code?

Thanks

Try this

const curvePoints = [];
        fetch("./src/curve.json").then((res) => { return res.json(); }).then((data) => {
            data.points.forEach(element => {
                curvePoints.push(new THREE.Vector3(element.x, element.y, element.z));
            });
          console.log(curvePoints);

          const curve = new THREE.CatmullRomCurve3(curvePoints);
          const points = curve.getPoints(11);
          const geometry = new THREE.BufferGeometry().setFromPoints(points);
          const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
          const curveObject = new THREE.Line(geometry, material);

          this.scene.add(curveObject);
        });

@anidivr So, the error is gone and it worked! But how? If I logged ‘curvePoints’ after the fetch it prints correct values! So the data did transfer to the array correctly?

Thanks for the fix.

@anidivr Does is it have anything to do with syncing and .then? The time the curve is being generated, the array hasn’t been populated yet, no?

Yes. Whenever you run code in a then (async), assume it might take a second before its executed. If anything depends on it, it needs to be included in the then.

Thanks for the replay, but if you don’t mind me asking one more question, in my code I have the async function, then right after it a console.log and it print correctly with the array that is, how come the log read the data but not the curve.getPoints?

Its just lucky timing. That’s the major frustration with async code. It might appear to work until you add more CPUs.

So basically CatmullRomCurve3 needs a minimum points of two to draw a curve, if you check CatmullRomCurve3 code, you’ll find a subVectors operation which requires two vectors.

Try to check if your array has a minimum of two vector3s before applying the function