TypeError: Cannot set property data of #<Object> which has only a getter

4,696 views
Skip to first unread message

James C.

unread,
Mar 4, 2011, 9:19:20 PM3/4/11
to Express
I just upgraded node to 0.42 and I'm getting this strange error that
does not seem to be very helpful (to me at least). anyone know whats
going on?

TypeError: Cannot set property data of #<Object> which has only a
getter
at Object.merge (/usr/local/lib/node/.npm/connect/1.0.3/package/
lib/utils.js:55:14)
at Object.Cookie (/usr/local/lib/node/.npm/connect/1.0.3/package/
lib/middleware/session/cookie.js:26:22)
at /usr/local/lib/node/.npm/connect/1.0.3/package/lib/middleware/
session.js:316:23
at /usr/local/lib/node/.npm/connect-mongodb/0.1.1/package/lib/
connect-mongodb.js:133:9
at [object Object].<anonymous> (/usr/local/lib/node/.npm/mongodb/
0.9.1/package/lib/mongodb/collection.js:447:35)
at [object Object].emit (events.js:45:17)
at [object Object].<anonymous> (/usr/local/lib/node/.npm/mongodb/
0.9.1/package/lib/mongodb/db.js:83:12)
at [object Object].emit (events.js:42:17)
at Socket.<anonymous> (/usr/local/lib/node/.npm/mongodb/0.9.1/
package/lib/mongodb/connection.js:82:16)
at Socket.emit (events.js:42:17)
Message has been deleted

vision media [ Tj Holowaychuk ]

unread,
Mar 4, 2011, 9:36:25 PM3/4/11
to expre...@googlegroups.com
connect-mongodb is probably not updated to work with connect 1.0. they should check out what connect-redis does, things
have changed slightly for the data stores


--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.




--
Tj Holowaychuk
Vision Media
President & Creative Lead

James C.

unread,
Mar 4, 2011, 10:09:07 PM3/4/11
to Express
Thanks for the quick reply. Not sure where to go from here. It seems
to only be happening on put and delete requests. Any ideas? Thanks

James

On Mar 4, 9:36 pm, "vision media [ Tj Holowaychuk ]" <t...@vision-
media.ca> wrote:
> connect-mongodb is probably not updated to work with connect 1.0. they
> should check out what connect-redis does, things
> have changed slightly for the data stores
>

James Charlesworth

unread,
Mar 5, 2011, 8:02:11 AM3/5/11
to Express
Okay, looks like connect-mongodb works fine with connect 1.0.  My issue was fixed by setting 'app.use(express.methodOverride());'
after 'app.use(express.bodyParser());' Must have missed this the first time in the docs. http://expressjs.com/guide.html#HTTP-Methods

Casey Banner

unread,
Mar 5, 2011, 4:44:17 PM3/5/11
to expre...@googlegroups.com
I'm having this same problem, except on GET requests as well.

con...@1.0.3
connect...@0.1.1
exp...@2.0.0beta
mon...@0.9.1

Node 0.4.2.

Configuration Code:
var MongoStore = require('connect-mongodb');

// Setup
var app = module.exports = express.createServer();

app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
secret: settings.secret,
store: new MongoStore({dbname: 'uwsched'})
}));
app.use(app.router);
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
app.use(express.static(__dirname + '/public'));
});

Traceback:
6 Mar 04:39:48 - [ERROR] TypeError


TypeError: Cannot set property data of #<Object> which has only a getter
at Object.merge

(/home/kcbanner/local/node/lib/node/.npm/connect/1.0.3/package/lib/utils.js:55:14)
at Object.Cookie
(/home/kcbanner/local/node/lib/node/.npm/connect/1.0.3/package/lib/middleware/session/cookie.js:26:22)
at /home/kcbanner/local/node/lib/node/.npm/connect/1.0.3/package/lib/middleware/session.js:316:23
at /home/kcbanner/local/node/lib/node/.npm/connect-mongodb/0.1.1/package/lib/connect-mongodb.js:133:9


at [object Object].<anonymous>

(/home/kcbanner/local/node/lib/node/.npm/mongodb/0.9.1/package/lib/mongodb/collection.js:447:35)


at [object Object].emit (events.js:45:17)
at [object Object].<anonymous>

(/home/kcbanner/local/node/lib/node/.npm/mongodb/0.9.1/package/lib/mongodb/db.js:83:12)


at [object Object].emit (events.js:42:17)
at Socket.<anonymous>

(/home/kcbanner/local/node/lib/node/.npm/mongodb/0.9.1/package/lib/mongodb/connection.js:82:16)


at Socket.emit (events.js:42:17)

As Tj mentioned, most likely a compatibility issue. Going to look into
that next.

-Casey

Darrell Banks

unread,
Mar 6, 2011, 10:31:06 AM3/6/11
to expre...@googlegroups.com
On Sat, Mar 5, 2011 at 4:44 PM, Casey Banner <kcba...@gmail.com> wrote:
I'm having this same problem, except on GET requests as well.

con...@1.0.3
connect...@0.1.1
exp...@2.0.0beta
mon...@0.9.1


Hello all, I fixed this error by ensuring that my node was @0.2.6, express was @1.0.7, and connect was @0.5.10. Try rolling back to those versions, hope this helps!!
 

vision media [ Tj Holowaychuk ]

unread,
Mar 6, 2011, 2:03:07 PM3/6/11
to expre...@googlegroups.com
like i said the mongodb session store needs to be updated to support connect 1.x

--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.

Casey Banner

unread,
Mar 6, 2011, 3:33:23 PM3/6/11
to expre...@googlegroups.com
I'm working on a replacement. Should be something in the next few days.

vision media [ Tj Holowaychuk ]

unread,
Mar 6, 2011, 3:58:21 PM3/6/11
to expre...@googlegroups.com
reference connect-redis if you need. the only thing new really is accessing the max-age from the session's cookie like below, when its not a number aka "req.session.expires = false" it is a browser session cookie so you have to arbitrarily set the TTL to something reasonable, I just have it set to a day for connect-redis

var maxAge = sess.cookie.maxAge
 , ttl = 'number' == typeof maxAge
   ? maxAge / 1000 | 0
   : oneDay
 , sess = JSON.stringify(sess);

Anthony Crognale

unread,
Mar 6, 2011, 11:40:20 PM3/6/11
to expre...@googlegroups.com

Hey all,

 

Update, I got connect-mongodb to run without creating errors in the console (albeit not working yet).

 

In /usr/local/lib/node/connect-mongodb/lib/ (assuming that’s you’re path), changed the set method:

 

mongoStore.set = function (hash, sess, fn) {

    try {

        var maxAge = sess.cookie.maxAge,

                ttl = 'number' == typeof maxAge

                ? maxAge / 1000 | 0

                : oneDay

                , sessd = JSON.stringify(sess);

        sess._id = hash;

        //console.log(hash)

      collection.update({_id: hash}, [ttl,sessd], {upsert: true}, function (err, data) {

        if (data) {

          delete data._id;

          //console.log('data');

        }

        if (fn) {

          //console.log('fn');

          fn.apply(this, arguments);

        }

      });

    } catch (exc) {

      if (fn) {

        fn(exc);

      }

    }

  };

 

Although I don’t think it changes much, I tried editing the get method to resemble the connect-redis version:

 

mongoStore.get = function(hash,fn) {

        collection.findOne({_id: hash}, function(err,data) {

                try {

                        if(!data) return fn();

                        fn(null,JSON.parse(data.toString()));

                } catch (err) {

                        fn(err);

                }

        });

};

 

After running with mongostore, I was able to log the hash to the console and confirm that it matched the hash inside of the cookie as well as the expiration date. It’s still not working though as I’m not able to access the session in the app, tried rendering the id of something I set in the session to a view but it’s coming up as undefined. I’ll hack at it more tomorrow.

 

Hope this helps,

 

-Anthony C

Casey Banner

unread,
Mar 8, 2011, 12:33:00 AM3/8/11
to expre...@googlegroups.com
Hey guys,

I have a replacement ready here: https://github.com/kcbanner/connect-mongo

Just finished the first iteration, so docs are coming soon. However,
there are tests for each method of the store.

The major pitfall with the old library was that it was trying to save
the session object directly to the database, however Connect assumes
that it will be JSON.stringify()ed first. So, more data fields than
Connect intended were making it into the DB, and this was causing
merge to barf when the session was eventually loaded. Basically I just
JSON.stringify the session and put that into a mongo document. This
kinda feels kludgy, but it has the benefit of making this library
future-proof for changes to the structure of sessions.

Let me know what you think. I'll put it into npm when I have time (very soon).

-Casey

vision media [ Tj Holowaychuk ]

unread,
Mar 8, 2011, 11:41:41 AM3/8/11
to expre...@googlegroups.com
you dont _have_ to, but JSON will work best, I believe in a few spots I do new Date() but you can still pass a valid date to that so it should work fine if you just have a mongo document, but im not sure how well a Session will be serialized to BSON with mongo, havent tried

James Charlesworth

unread,
Mar 10, 2011, 9:11:46 PM3/10/11
to expre...@googlegroups.com
Thank you for your time updating this and providing it to the community!

Tony Milne

unread,
Mar 22, 2011, 1:44:58 AM3/22/11
to Express
The error was occurring in Express session.js and cookie.js (as a
result of the connect-mongodb code/data structure).

Basically, the cookie constructor was trying to merge the properties
of the options object being passed in, but choked on the data
property, because the cookie.js file only provides a get data() but no
set data().

A hack to get around this is to strip out the cookie.data in connect-
mongodb get() - which by the way, is a totally redundant copy of the
rest of the cookie data.

Replacing the existing mongoStore.get function with this one should
make the connect-mongodb lib work once again:

mongoStore.get = function (hash, fn) {
collection.findOne({_id: hash}, function (err, data) {
try {
if (data) {
delete data._id;
if (data.cookie && data.cookie.data) {
delete data.cookie.data;
}
}
// TODO: fail if expired
fn(null, data);
} catch (exc) {
fn(exc);
}
});
};

Casey Banner

unread,
Mar 22, 2011, 12:33:14 PM3/22/11
to expre...@googlegroups.com
Check out the connect-mongo module. I wrote a new mongo session store
when Connect 1.0.x came out, it may work better. I believe the cookie
serializes to JSON without the duplicate data.

Reply all
Reply to author
Forward
0 new messages