Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toJSON: Cannot read property 'prototype' of null at Function.toObject #730

Closed
tamird opened this issue Mar 27, 2017 · 5 comments
Closed

Comments

@tamird
Copy link

tamird commented Mar 27, 2017

When calling MessageObject.toJSON(), I get the following error:

Cannot read property 'prototype' of null at Function.toObject

Which occurs in this function:

                TimeSeriesQueryRequest.toObject = function toObject(message, options) {
                    if (!options)
                        options = {};
                    var object = {};
                    if (options.arrays || options.defaults)
                        object.queries = [];
                    if (options.defaults) {
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.start_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.start_nanos = options.longs === String ? "0" : 0;
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.end_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.end_nanos = options.longs === String ? "0" : 0;
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.sample_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.sample_nanos = options.longs === String ? "0" : 0;
                    }
                    if (message.start_nanos != null && message.hasOwnProperty("start_nanos"))
                        if (typeof message.start_nanos === "number")
                            object.start_nanos = options.longs === String ? String(message.start_nanos) : message.start_nanos;
                        else
                            object.start_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.start_nanos) : options.longs === Number ? new $util.LongBits(message.start_nanos.low >>> 0, message.start_nanos.high >>> 0).toNumber() : message.start_nanos; // <-- unguarded access to `$util.Long`!!
                    if (message.end_nanos != null && message.hasOwnProperty("end_nanos"))
                        if (typeof message.end_nanos === "number")
                            object.end_nanos = options.longs === String ? String(message.end_nanos) : message.end_nanos;
                        else
                            object.end_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.end_nanos) : options.longs === Number ? new $util.LongBits(message.end_nanos.low >>> 0, message.end_nanos.high >>> 0).toNumber() : message.end_nanos;
                    if (message.queries && message.queries.length) {
                        object.queries = [];
                        for (var j = 0; j < message.queries.length; ++j)
                            object.queries[j] = $root.cockroach.ts.tspb.Query.toObject(message.queries[j], options);
                    }
                    if (message.sample_nanos != null && message.hasOwnProperty("sample_nanos"))
                        if (typeof message.sample_nanos === "number")
                            object.sample_nanos = options.longs === String ? String(message.sample_nanos) : message.sample_nanos;
                        else
                            object.sample_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.sample_nanos) : options.longs === Number ? new $util.LongBits(message.sample_nanos.low >>> 0, message.sample_nanos.high >>> 0).toNumber() : message.sample_nanos;
                    return object;
                };

This code was generated with --strict-long, so I'm not really sure why util.Long is undefined, or why any of the code paths above need to be guarded with if ($util.Long) {.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 27, 2017

--strict-long has no effect on generated code. It just makes sure to document long fields as Long instead of number|Long for TypeScript. The CLI basically just wraps up what the encoder, decoder and converter generate at runtime anyway in a reflection based scenario.

This code was generated with --strict-long, so I'm not really sure why [...] any of the code paths above need to be guarded with if ($util.Long) {.

Currently, generated code aims to remain compatible with any configuration (with or without long.js), in case it is shared or otherwise depended upon by another application.

@tamird
Copy link
Author

tamird commented Mar 27, 2017

That's fine; what's the story with $util.Long being undefined?

@dcodeIO
Copy link
Member

dcodeIO commented Mar 27, 2017

That's fine; what's the story with $util.Long being undefined?

Looks like long.js isn't present. You can check this by evaluating protobuf.util.Long. If it's unset, you can also explicitly set it, like so:

protobuf.util.Long = require("long");
protobuf.configure();

@tamird
Copy link
Author

tamird commented Mar 27, 2017

long.js is present; I can do what you suggest, but why is it not being picked up automatically?

@dcodeIO
Copy link
Member

dcodeIO commented Mar 27, 2017

For reference, this is about how the process works:

  • inquire("long") (ref) tries to load the long library, which requires a global require function to be available
  • if it cannot be required, it looks for it in global.dcodeIO.Long and if it isn't there either, it sets protobuf.util.Long to null
  • AMD modules specify "long" as a dependency and it's set like shown above if it is available (ref)

Referring to the error you see: Long conversion to strings is available with long.js only. Conversion to (a possibly unsafe) number should work even if long.js isn't present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants