Node JS [Object Map] while writing object to file

write object in file javascript
write map to file js
node write js to file
javascript serialize object to file
node repl write to file
nodejs dump variable to file
node writefilesync object
node writefile object

I read many posts on stackoverflow and other tutorial sites for writing object/JSON to a file, but none of the solutions worked for me.

1) Code:

let messages = await fetchMessages()
console.log(messages)    // Prints an object
fs.writeFileSync('./msgdata.json', messages , 'utf-8'); 

2) Also tried,

fs.writeFileSync('./msgdata.json', JSON.stringify(messages) , 'utf-8'); 

3) Also tried,

fs.writeFile(), but get same output as above.

msgdata.json: (For 1)

[object Map]

msgdata.json: (For 2 & 3)

{}

Can someone please point out what could be causing this?

## Output of console.log(messages) ##
OUTPUT contains 10 more such objects having different id's:

channel:
   TextChannel {
     type: 'text',
     id: '424825532274253312',
     name: 'request',
     position: 69,
     parentID: '397363224286473987',
     permissionOverwrites: [Object],
     topic: null,
     nsfw: false,
     lastMessageID: '427143105410760704',
     guild: [Object],
     messages: [Object],
     _typing: Map {} },
  id: '427142596817846272',
  type: 'DEFAULT',
  content: '**Select your emoji:** __***Group 9:***__',
  author:
   ClientUser {
     id: '407083773537350272',
     username: 'Bot',
     discriminator: '9256',
     avatar: '9c374e719ba2ab4e69fd577005b635bf',
     bot: true,
     lastMessageID: null,
     lastMessage: null,
     verified: true,
     email: null,
     localPresence: {},
     _typing: Map {},
     friends: Collection {},
     blocked: Collection {},
     notes: Collection {},
     premium: null,
     mfaEnabled: false,
     mobile: null,
     settings: [Object],
     guildSettings: Collection {} },
  member:
   GuildMember {
     guild: [Object],
     user: [Object],
     _roles: [Array],
     serverDeaf: false,
     serverMute: false,
     selfMute: undefined,
     selfDeaf: undefined,
     voiceSessionID: undefined,
     voiceChannelID: undefined,
     speaking: false,
     nickname: null,
     joinedTimestamp: 1517127343434,
     lastMessageID: null,
     lastMessage: null },
  pinned: false,
  tts: false,
  nonce: undefined,
  system: false,
  embeds: [],
  attachments: Collection {},
  createdTimestamp: 1521909131007,
  editedTimestamp: null,
  reactions:
   Collection {
     'taillow:417281639777959940' => [Object],
     'shroomish:417281639899463680' => [Object],
     'sableye:417281640197521419' => [Object],
     'ralts:417281642735075329' => [Object],
     'sentret:417281644001624076' => [Object],
     'shuppet:417281644291162132' => [Object],
     'torchic:417281647210397706' => [Object],
     'snubbull:417281647692480522' => [Object],
     'sunkern:417281647763783681' => [Object],
     'slowpoke:417281648653107200' => [Object],
     'teddiursa:417281649537974273' => [Object],
     'sneasel:417281649613471747' => [Object],
     'snorunt:417281649819123712' => [Object],
     'surskit:417281650163056640' => [Object],
     'qwilfish:417281654629859348' => [Object],
     'shelgon:417281654730522624' => [Object] },
  mentions:
   MessageMentions {
     everyone: false,
     users: Collection {},
     roles: Collection {},
     _content: '**Select your emoji:** __***Group
9:***__',
     _client: [Object],
     _guild: [Object],
     _members: null,
     _channels: null },
  webhookID: null,
  hit: null,
  _edits: [] },

This is because the object returned is a Map object (MDN). When you JSON.strigify a Map object, it always returns {}. There are two ways to get readable JSON that stores your map. The first is to loop over all the entries and create a JSON (taking in consideration the keys and values). That should be simple to achieve.

Another way is to create an array from the Map and then stringify it.

fs.writeFileSync('./msgdata.json', JSON.stringify([...myObject]) , 'utf-8'); 

write a javascript object to a file in node, Thanks Stephan Bijzitter for the link. My problem can be solved like so: var fs = require('fs') var util = require('util') var obj = {a: 1, b: 2} fs. In my experience JSON.stringify is slightly faster than util.inspect. I had to save the result object of a DB2 query as a json file, The query returned an object of 92k rows, the conversion took very long to complete with util.inspect, so I did the following test by writing the same 1000 record object to a file with both methods.

You can define Map.prototype.toJSON which works, but it isn't standard and is discouraged. It is automatically called by JSON.stringify if it finds it.

Map.prototype.toJSON = function() {return [...this];};
console.log(JSON.stringify(messages));

A better way is to define your own replacer function (and reviver function too if you need to reconstruct map from JSON). Here I also wrap the map representing array in a special object to tell maps and ordinary arrays apart in JSON:

function replacer (key, value) {
    if (value instanceof Map) {
        return {
            _type: "map",
            map: [...value],
        }
    } else return value;
}

function reviver (key, value) {
    if (value._type == "map") return new Map(value.map);
    else return value;
}

let str = JSON.stringify(messages, replacer);
let msg = JSON.parse(str, reviver);

The error you are getting about circular structure means that some objects/arrays there contain references to itself. When you store messages you don't need to store all the information related to the channels etc and instead only store ids. So that means extending replacer for TextChannels, ClientUsers, GuildMembers etc:

if (value instanceof TextChannel) {
  return {
    _type: "TextChannel",
    id: value.id,
  };
}

Node.js — Write a JSON Object to a File, When working on a new feature or app idea, storing data on the file system can be a good solution. You can skip the database setup and save� Node.JS Write to File. Node.JS Write to File – To write content to a file in Node.js, use writeFile function of node fs module.. Syntax of writeFile; Example 1; Example 2 – With encoding mentioned

var util = require('util');
fs.writeFileSync('./data.json', util.inspect(obj) , 'utf-8');

Ref. Write objects into file with Node.js

How to write a JSON object to file in Node.js, Sometimes the best way to store some data in a Node.js application is to save it to the filesystem. If you have an object that can be serialized to� The latter, known as object literal syntax, is preferred. We can specify the contents of objects using object literal syntax. We can specify member names and values at initialization time:

Node.js Write JSON Object to File - Example Script, Node.js Write JSON Object to File - In this tutorial, learn to write a JSON Object to a file using JSON.stringify() function and FS.writeFile() function with examples. Returns a boolean asserting whether a value has been associated to the key in the Map object or not. Map.prototype.keys() Returns a new Iterator object that contains the keys for each element in the Map object in insertion order. Map.prototype.set(key, value) Sets the value for the key in the Map object. Returns the Map object. Map.prototype

Node.js v14.7.0 Documentation, References to objects with a lifespan longer than that of the native method Enabling. package.json "type" field; Package scope and file extensions; --input- type flag _final(callback); Errors while writing; An example writable stream; Decoding buffers in a writable stream Map keys and Set items are compared unordered. Filestream in Node.js. Node makes extensive use of streams as a data transfer mechanism. For example, when you output anything to the console using the console.log function, you are actually using a stream to send the data to the console. Node.js also has the ability to stream data from files so that they can be read and written appropriately.

Objects, Every piece of data is stored in its file by the key. It's easy to find a We can use square brackets in an object literal, when creating an object. Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

Comments
  • Are you sure console.log(messages) doesn't log {} on the console?
  • @vibhor1997a, yes pretty sure
  • Thanks for the answer, I'll try it out and update here
  • (node:4252) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Converting circular structure to JSON (node:4252) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. Tried your solution and i am getting this error...
  • @eNthUsiAst Could you please mention what console.log(messages) prints?
  • Added it @Shiven
  • @eNthUsiAst Well, wow. The [object Map] seems to be weird, because the output seems to be JSON. But actually, could you tell me what console.log(JSON.stringify(messages)) instead of the straightforward log prints? I believe it would be empty, is it?
  • Wow! This was really cool thing I learnt. What is the ...value syntax? And if i use the first approach Map.prototype.toJSON, then how do i call it?
  • JSON.stringify will call toJSON method when it's present on a map. [...value] is a spread syntax (ES6+) and will convert map to array [[key, value], [key value],...]
  • Okay thanks understood...Getting this error while trying your solution... ``(node:4252) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Converting circular structure to JSON (node:4252) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.` Tried your solution and i am getting this error...`
  • But what is each individual message type (stuff before channel:)? You need a replacer either for "foreign" classes (as I put in my edit) or for message itself to replace "foreign" classes by their ids.
  • I am not sure if i understood it, will it be possible for you to edit your answer how should i do it in actual? :(