[2.0-B5] Cannot read property 'freeze' of null

After upgrading to 2.0.0-beta5 from 1.8 we’re getting these console messages and can’t figure out why they’re happening. I searched our code and we don’t call freeze anywhere. Any idea on what could be causing it? I went to the API and searched for ‘freeze’ and got no matches. This message only happens on pages with a GoJS Diagram so I’m thinking it’s a GoJS error.

property set error: TypeError: Cannot read property 'freeze' of null

Is there a stack trace? Any suggestions for how to reproduce the error?

There is no stack trace but I did get a pause on exception breakpoint. This is the GoJS code where it’s happening.

This is our code.

If there are any detailed values you want from these screenshots let me know. Hopefully this at least gets us a starting point as making a reproducible demo from our app might be tough.

Do you have a starter GoJS template that I could use on CodeSandbox or any other online sandbox? If so I could try starting with that.

We always have codepen: https://codepen.io/simonsarris/pen/zmePzE?editors=1010

I’m interested to know what’s causing this, so anything you can give us to reproduce helps. You can always email, too, to attach files.

Well I was able to reproduce it then I had a hunch what was causing the problem after looking at the data. Our link points are stored as array of strings instead of numbers. After changing to numbers the error went away. Here it is with the error if you want to see it.

We are working on a new release so it shouldn’t be a problem to fix this. I wonder for your existing customers on 1.8 if you might want to convert from string to number in GoJS 2.0 to keep this error from happening? Or maybe a specific warning if you can do that?

I think we originally stored as int then saw decimal numbers like 256.58359213500125 going across for saves and why we changed to string. My thinking was to use string to avoid any floating point precision problems between JavaScript and Java.

If it was working in 1.8 and breaks 2.0, we definitely want to investigate it.

edit: I see that what you made has the console errors, I’ll take a look.

@simon The CodeSandbox currently has strings for points in data.js and should have errors in the console at the bottom if you open it. The application seems to work fine but shows the errors. Let me know if you’re not getting console errors

Here is it with 1.8 and no errors.

I think this might be an error, but misreported. What you should really be getting is:

property set error: Error: Link.points array must contain only an even number of numbers or objects with x and y properties, not: [object Object],[object Object]

And you should be getting it in both 1.8 and 2.0, if you use the go-debug version. You’d need to do:

import * as go from 'gojs/release/go-debug'

to use that.

Aside from that, GoJS is giving an error where it shouldn’t be in 2.0. But you may actually have to change your data to be correct, here.

Just making sure this is valid points data:

    points: [
        x: 135,
        y: 270
        x: 255,
        y: 270

Yes, that is valid. The only issue seems to be with the string values.

Just as an example, here’s 1.8 go-debug.js failing in the same way: https://codepen.io/simonsarris/pen/dgagpN?editors=1011

That 2.0 go.js isn’t silently failing is our fault, but it ought to fail when using the Debug library for both versions.

So apparently go-debug.js will show errors and warnings that go.js won’t? I never knew this and guess we should use go-debug.js for development? If so now I need to see if there’s a way to do have Node import go-debug.js for development and go.js for production, especially since we import GoJS in several source files. If you know of an easy way to do this I would appreciate any advice.

Turning on debug in one file our app won’t run. It gets this error:

Error: A Binding can only be applied to a GraphObject or RowColumnDefinition, not to: Shape(None)#194

This is the code that’s failing (note ‘Shape’):

make('Shape', { stroke: null, fill: '#fff' }, new Binding('geometry', 'iconSource'))

But the object way works:

make(Shape, { stroke: null, fill: '#fff' }, new Binding('geometry', 'iconSource'))

Hopefully I didn’t open a big can of worms turning on debug!

Yeah, a huge number of errors and warnings. To keep the payload of the library down we have two versions, since long error strings everywhere takes up a considerable amount of kb, and because many of the checks in go-debug can impact performance.

Hopefully I didn’t open a big can of worms turning on debug!

Well. Can of worms or ripping off the bandaid, however you choose to see it :)

It’s good form to use go-debug. Just make sure you are using go.js in production for performance.

Something’s odd about your scenario. Here’s an example that uses:

$('Shape', { stroke: null, fill: '#fff' }, new go.Binding('geometry', 'iconSource')),

But seems to have no issue: https://codepen.io/simonsarris/pen/QZYJxE?editors=1011

What else is different about your code? Note that I added a go. prefix to the Binding.

The basic rules of using the GoJS library are mentioned at GoJS Introduction -- Northwoods Software

@simon We started doing this to be consistent how we import from other libraries and thought it might help if you support tree shaking down the road.

import { Binding, GraphObject, Map, Margin, Node, Panel, Shape, Size, Spot, TextBlock } from 'gojs';

Maybe that’s a bad idea and possibly causes problems with singletons, statics, etc?

I’m not sure that doing that is a problem in itself. It should be OK to do.

Are you sure that’s why the error is appearing? By that I mean, if you write import * as go ... does it fix the error? I think its something else, but I’m not sure.

I just changed the original sandbox I created and added go-debug.js to Diagram.js and get the same error as my app.

Here’s a thought - if I change one file’s import to go-debug do I have to change them all to go-debug?

^^^ EDIT: Just proved this statement above. Looks like all or none have to be go-debug.

The GraphObject.make static function takes either a string or a reference to a class constructor.

In the latter case, the argument is a function and make can call it to construct an object and then proceed to initialize it from the rest of the arguments. So if you had done:

import * as go from "gojs";

and if you then call:

go.GraphObject.make(go.TextBlock, . . .)

the expression go.TextBlock will evaluate to a class constructor, and everything is normal.

But if you did:

import { TextBlock } from "gojs";

then you would be able to call:

go.GraphObject.make(TextBlock, . . .)

In the former case where the first argument is a string, the make function looks up the string in the collection of builders that were defined using GraphObject.defineBuilder, such as “TreeExpanderButton”. If it doesn’t find it there it looks in the go object. So if you did:

go.GraphObject.make("TextBlock", . . .)

then the make function would evaluate:


Of course that would be a problem if there is no go object!

On the other issue, the x and y values for points must be numbers. That’s just the way it is. But I believe all of the following are valid values for the Link.points property:

[ 10, 20, 20, 20, 40, 60, 50, 60 ]
[ { x: 10, y: 20 }, { x: 20, y: 20 }, { x: 40, y: 60 }, { x: 50, y: 60 } ]
[new go.Point(10, 20), new go.Point(20, 20), new go.Point(40, 60), new go.Point(50, 60) ]
new go.List().addAll([new go.Point(10, 20), new go.Point(20, 20), new go.Point(40, 60), new go.Point(50, 60) ])

The Model.toJson method produces the first rendering when given a List of Points that is the value of the “points” property of a data object being serialized.