olefrank olefrank - 2 months ago 23
JSON Question

Mongoose: TypeError: Method Uint8Array.length called on incompatible receiver

I'm making a small website with i18n. When starting I used local json files, but after switching to mongodb I experience an error I don't understand. A good explanation is highly appreciated.

The error I get is this:


TypeError: Method Uint8Array.length called on incompatible receiver [object Object]


I structure i18n data with "da" and "en" properties. I then use a method for filtering relevant language.

Here are examples of my data, both json and corresponding mongoose result. Both copied from terminal (printed with
console.log
):

json

[ { lang: { da: 'Dansk', en: 'Danish' }, rating: 5 },
{ lang: { da: 'Engelsk', en: 'English' }, rating: 5 },
{ lang: { da: 'Tysk', en: 'German' }, rating: 5 } ]


mongoose

[ { _id: 57e2561369e4bc0a8ca6c630,
lang: { da: 'Dansk', en: 'Danish' },
rating: 5,
id: '57e2561369e4bc0a8ca6c630' },
{ _id: 57e2561369e4bc0a8ca6c631,
lang: { da: 'Engelsk', en: 'English' },
rating: 5,
id: '57e2561369e4bc0a8ca6c631' },
{ _id: 57e2561369e4bc0a8ca6c632,
lang: { da: 'Tysk', en: 'German' },
rating: 5,
id: '57e2561369e4bc0a8ca6c632' } ]


filterLanguage method

var traverse = require('traverse');
var filterLanguage = function(language, obj) {
return traverse(obj).map(function (item) {
if (this.key === language) {
this.parent.update(item);
}
});
};


So
filterLanguage('da', languages);
should return something like:

[ { lang: 'Dansk', rating: 5 },
{ lang: 'Engelsk', rating: 5 },
{ lang: 'Tysk', rating: 5 } ]


filterLanguage()
works on a local, valid JSON file but not on the Mongoose result set...

I tried
JSON.stringify(obj)
. I also tried setting
toObject()
method in Mongoose models but no luck.

What am I doing wrong and how can I fix it?

--------- EDIT ---------

Model

var mongoose = require('mongoose');
var languageSchema = mongoose.Schema({
local: {
lang: { da: String, en: String },
rating: Number
}
});
module.exports = mongoose.model('Language', languageSchema);


Query

language.find({}, function(err, results) {
var obj = filterLanguage(lang, results.languages);
console.log(obj);
});


I tried setting
toObject
on the schema like this:

languageSchema.set('toObject', { virtuals: true });

Answer

The error you get is related to traverse not being able to handle ObjectId instances in your results array.

Since it looks like you don't use _id or id, the easiest way to fix this is to exclude those properties from the result documents:

language.find({}, '-_id -id', function(err, results) { ... })

(-id is probably superfluous, because it's a virtual that depends on _id)