{"record":{"id":"51a4c7612bac6c7b","repo":"SignalR/SignalR","slug":"when-calling-ko-tojs-pass-the-object-you-want-to","errorCode":null,"errorMessage":"When calling ko.toJS, pass the object you want to convert.","messagePattern":"When calling ko\\.toJS, pass the object you want to convert\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"samples/Microsoft.AspNet.SignalR.LoadTestHarness/Scripts/knockout-2.1.0.debug.js","lineNumber":1275,"sourceCode":"    return ko.hasPrototype(instance, ko.dependentObservable);\n};\n\nvar protoProp = ko.observable.protoProperty; // == \"__ko_proto__\"\nko.dependentObservable[protoProp] = ko.observable;\n\nko.dependentObservable['fn'] = {};\nko.dependentObservable['fn'][protoProp] = ko.dependentObservable;\n\nko.exportSymbol('dependentObservable', ko.dependentObservable);\nko.exportSymbol('computed', ko.dependentObservable); // Make \"ko.computed\" an alias for \"ko.dependentObservable\"\nko.exportSymbol('isComputed', ko.isComputed);\n\n(function() {\n    var maxNestedObservableDepth = 10; // Escape the (unlikely) pathalogical case where an observable's current value is itself (or similar reference cycle)\n\n    ko.toJS = function(rootObject) {\n        if (arguments.length == 0)\n            throw new Error(\"When calling ko.toJS, pass the object you want to convert.\");\n\n        // We just unwrap everything at every level in the object graph\n        return mapJsObjectGraph(rootObject, function(valueToMap) {\n            // Loop because an observable's value might in turn be another observable wrapper\n            for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++)\n                valueToMap = valueToMap();\n            return valueToMap;\n        });\n    };\n\n    ko.toJSON = function(rootObject, replacer, space) {     // replacer and space are optional\n        var plainJavaScriptObject = ko.toJS(rootObject);\n        return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space);\n    };\n\n    function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) {\n        visitedObjects = visitedObjects || new objectLookup();\n","sourceCodeStart":1257,"sourceCodeEnd":1293,"githubUrl":"https://github.com/SignalR/SignalR/blob/693053b89a9e1f5ce819e3233ed159a6409de22b/samples/Microsoft.AspNet.SignalR.LoadTestHarness/Scripts/knockout-2.1.0.debug.js#L1257-L1293","documentation":"ko.toJS recursively unwraps observables in an object graph to produce a plain JavaScript object. It requires at least one argument — the root object to convert. If called with zero arguments (arguments.length === 0), it throws immediately. This prevents undefined behavior from processing an undefined root.","triggerScenarios":"Calling ko.toJS() with no arguments. Calling ko.toJSON() with no arguments (which internally calls ko.toJS). A variable that was expected to hold the root object is undefined when passed.","commonSituations":"A function that conditionally calls ko.toJS but the argument is undefined in some code paths. A serialization helper that passes an optional parameter without a default.","solutions":["Ensure the root object argument is passed and is defined before calling ko.toJS.","Add a default or guard: ko.toJS(rootObject || {})."],"exampleFix":"// before — argument may be undefined\nvar plain = ko.toJS(maybeUndefined);\n// after — provide a default\nvar plain = ko.toJS(maybeUndefined || {});","handlingStrategy":"validation","validationCode":"// Always pass a root object to ko.toJS\nfunction safeToJS(rootObject) {\n    if (arguments.length === 0 || rootObject === undefined) {\n        console.warn('ko.toJS called without a root object');\n        return null;\n    }\n    return ko.toJS(rootObject);\n}","typeGuard":"function isDefined(val) {\n    return val !== undefined && val !== null;\n}","tryCatchPattern":null,"preventionTips":["Always pass an explicit root object to ko.toJS() and ko.toJSON().","Use a default value when the source is optional: ko.toJS(rootObject || {}).","Add parameter validation in helper functions that wrap ko.toJS."],"tags":["knockout","tojs","serialization","validation"],"backgroundTag":null,"analyzedSha":"693053b89a9e1f5ce819e3233ed159a6409de22b","analyzedAt":"2026-08-13T22:23:59.793Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}