Cannot use Map read from MongoDb

I wrote a function that stores a Map object in MongoDb. However, when I read the object back elsewhere, as in:

var map=this.projectData.storedMap;
map.forEach ...

It states that map.forEeach is not a function. I tried let x=new Map() and assign the object but the result is still the same.

I use map because I need to ensure a particular order of properties (sorted).

>Solution :

Meteor supports complex custom data types via EJSON: https://docs.meteor.com/api/ejson.html

Every insert will try to resolve complex objects for registered EJSON extensions! One thing though, it requires monkey patching the Map class.
The following code defines a custom EJSON type for Map:

import { EJSON } from 'meteor/ejson'

Map.prototype.toJSONValue = function () {
  const self = this
  return [...self.entries()]
}

Map.prototype.typeName = function () {
  return 'Map';
}

EJSON.addType('Map', function fromJSONValue(entries) {
  return new Map(entries)
})

This example shows, that the order of the the keys is preserved even after the value has been set again:

const map = new Map()

map.set('foo', 1)
map.set('bar', 3)
map.set('baz', 5)
map.set('moo', 7)
map.set('foo', 11) // set again

const dataStr = EJSON.stringify({ data: map })

// {"data":{"$type":"Map","$value":[["foo",11],["bar",3],["baz",5],["moo",7]]}}

EJSON.parse(dataStr)
// { data: Map(4) { 'foo' => 11, 'bar' => 3, 'baz' => 5, 'moo' => 7 } }

Important here is to use map.entries() which returns an iterator that preservers insertion order, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries

Leave a Reply