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).
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