64

I'm using repl.it/languages/javascript.

Do I have to convert it to an object before I print it out?

I've tried

const mapObject = new Map();

mapObject.set(1, 'hello');

console.log(JSON.stringify(mapObject));
console.log(mapObject);

The results are always empty object.

When I use

console.log([...mapObject]);

It prints out an array format.

7
  • 4
    console.log(mapObject) works just fine in the latest Chrome and node7. What's your platform? Commented Aug 8, 2017 at 14:32
  • @georg repl.it/languages/javascript Commented Aug 8, 2017 at 14:33
  • 6
    Use console.dir instead of .log, and without stringifying. Commented Aug 8, 2017 at 14:33
  • 1
    @newguy: well, how about you drop them a line and ask to fix that? Commented Aug 8, 2017 at 14:34
  • @georg I still see empty objects on my browser after your edit. Commented Aug 8, 2017 at 14:37

9 Answers 9

77

There is a simpler solution you can try.

const mapObject = new Map();
mapObject.set(1, 'hello');

console.log([...mapObject.entries()]);
// [[1, "hello"]]

console.log([...mapObject.keys()]);
// [1]

console.log([...mapObject.values()]);
// ["hello"]

Sign up to request clarification or add additional context in comments.

3 Comments

Works well with stringify: console.log( JSON.stringify([... mapObject.entries()]) )
If I try this, I get an error saying "Type 'IterableIterator<string>' is not an array type". OK, in my case the Map ist more complicated than that defined in the snippet. But if the solution only works for those simple Maps it's not worth considering.
If you get an error similar to mentioned above ("Type 'IterableIterator<string>' is not an array type") you should use console.log(Array.from(mapObject.entries())); etc.
12

Simplest and most human readable option: console.table

const mapObject = new Map();
mapObject.set(1, 'hello');
mapObject.set(2, 'world');
mapObject.set('foo', 'bar');

console.table(mapObject);

NodeJS output looks like this:

┌───────────────────┬───────┬─────────┐
│ (iteration index) │  Key  │ Values  │
├───────────────────┼───────┼─────────┤
│         0         │   1   │ 'hello' │
│         1         │   2   │ 'world' │
│         2         │ 'foo' │  'bar'  │
└───────────────────┴───────┴─────────┘

Chrome dev tools console output looks like this:

enter image description here

Comments

10

Note: This answer is only relevant to the repl.it sandbox environment OP is using

Since you said in the comments that you're using repl.it, there's a trick you can use to write your own "logging strategy".

Note that you shouldn't use this trick in production, mainly because it edits a native prototype. In some Node environment, in your own code, it could be useful though.

The idea is to create an inspect method for Map that iterates over the entries:

Map.prototype.inspect = function() {
  return `Map(${mapEntriesToString(this.entries())})`
}

function mapEntriesToString(entries) {
  return Array
    .from(entries, ([k, v]) => `\n  ${k}: ${v}`)
    .join("") + "\n";
}

You can see that repl.it supports it here

console.log(new Map([["a", 1], ["b", 2]]));
// Logs:
/*
Map(
  a: 1
  b: 2
)
*/

2 Comments

Nice one. I just finished something similar, but I chose to bastardise their console.log instead :) repl.it/KBdU
@DaveSalomon Nice! Feels like "We're in an online sandbox environment; let's break all the native prototypes and default implementations!" ;) Still, both approaches can help in the debugging process, so it's nice to see what can be done.
9

For simple maps that are of depth 1, just use Object.fromEntries([...map]) to convert your object entries array back to a console loggable object:

const simpleObj = {
  a: [1, 2, 3],
  b: {c: {d: 42}}
};
const map = new Map(Object.entries(simpleObj));
console.log(Object.fromEntries([...map]));

This fails for complex nested maps, however. For that, we can recursively convert any Maps to objects and then log it as normal. Here's a proof-of-concept on a complex structure combining plain objects, Maps, arrays and primitives. Don't expect it to cover every edge case out of the box, but feel free to point out improvements.

const convertMapToObjDeeply = o => {
  const recurseOnEntries = a => Object.fromEntries(
    a.map(([k, v]) => [k, convertMapToObjDeeply(v)])
  );
  
  if (o instanceof Map) {
    return recurseOnEntries([...o]);
  }
  else if (Array.isArray(o)) {
    return o.map(convertMapToObjDeeply);
  }
  else if (typeof o === "object" && o !== null) {
    return recurseOnEntries(Object.entries(o));
  }
  
  return o;
};

const mkMap = o => new Map(Object.entries(o));

const map = mkMap({
  a: 42, 
  b: [1, 2, 3, mkMap({d: mkMap({ff: 55})})],
  c: mkMap({
    e: [4, 5, 6, {f: 5, x: y => y}, mkMap({g: z => "A"})]
  }),
  h: {i: mkMap({j: 46, jj: new Map([[[1, 6], 2]])})},
  k: mkMap({l: mkMap({m: [true, null, undefined]})})
});

console.log(convertMapToObjDeeply(map));

Comments

7

I realize this is most likely intended for the browser console but this also occurs in Node. So, you may use this in Node to view Maps (or an Object that may contain Maps):

import * as util from "util";

const map: Map<string, string> = new Map();
map.set("test", "test");

const inspected: string = util.inspect(map);

console.log(inspected);

Comments

4

Try this:

let mapObject = new Map();
mapObject.set("one", "file1");
mapObject.set("two", "file2");
mapObject.set("three", "file3");
console.log([...mapObject.entries()]);

the output will be:

[ [ 'one', 'file1' ], [ 'two', 'file2' ], [ 'three', 'file3' ] ]

The problem with this solution, is that the output changes if we add a previous string:

console.log("This is a map: " + [...mapObject.entries()]);

the output will be:

This is a map: one,file1,two,file2,three,file3

the solution can be found here

Comments

1

you can use console.log(mapObject.values())

1 Comment

All I see from this is [object Map Iterator] {}, in the CodePen console anyway.
-1

In my case (regular browser console in Chrome V 115, Immutable Map) I could use

console.dir(myMapObject.toJS());

It contained a great deal of information more than I needed, but better too much than too little.

Comments

-1

You can use this script to convert the map to a array and print it. Make sure that the entries in the map can be stringified.

function printMap(map) {
  const entries = map.entries();

    const arr = new Array();

    let entry = entries.next();

    while (!entry.done) {
      arr.push({ [entry.value[0]]: entry.value[1] });

      entry = entries.next();
    }

    return arr;
    
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.