Search code examples
javascriptnode.jscouchdbcradle

How can I call functions on documents retrieved from CouchDB?


I am using Cradle to store objects in CouchDB from my Node.js server. The objects contain functions....

function AnObject(a, b){
this.a = a; this.b = b;
this.addparts = function(){return this.a + this.b;};}

var cradle = require('cradle');
var db = new(cradle.Connection)('http://localhost', 5984, {cache: true, raw: false}).database('myDB');

var myObject = new AnObject(1, 2);
console.log("addparts:" + myObject.addparts());
db.save('myObjectId', myObject);

This works fine and the document is stored but when I retrieve it, I can no longer call the function on the returned document...

db.get('myObjectId', function(err, myRetrievedObject){
console.log("addparts:" + myRetrievedObject.addparts());
});

This fails with a (Property is not a function) Error..

node cradle_test

cradle_test.js:21
console.log("addparts:" + myRetrievedObject.addparts());
                                         ^
TypeError: Property 'addparts' of object {"_id":"myObjectId","_rev":"2-83535db5101fedfe30a1548fa2641f29","a":1,"b":2,"addparts":"function (){return this.a + this.b;}"} is not a function

Solution

  • CouchDB stores JSON. Functions are not valid JSON. Functions are never stored in the database.

    I recommend you move the functions out into a prototype.

    function AnObject(a, b){
        this.a = a; this.b = b;
    }
    
    AnObject.prototype.addparts = function(){
        return this.a + this.b;
    };
    
    db.get('myObjectId', function(err, myRetrievedObject){
        var obj = Object.create(AnObject.prototype);
        // for some value of extend ( https://github.com/Raynos/pd#pd.extend )
        extend(obj, myRetrievedObject);
        console.log("addparts:" + obj.addparts());
    });
    

    This way your not saving functions and you can still operate on your object using your methods. You just have to make sure that your retrieved object is made an instance of AnObject