最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Node JS [Object Map] while writing object to file - Stack Overflow

programmeradmin4浏览0评论

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: [] },

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: [] },
Share Improve this question edited Mar 25, 2018 at 16:27 asked Mar 25, 2018 at 6:45 user5763634user5763634 2
  • Are you sure console.log(messages) doesn't log {} on the console? – vibhor1997a Commented Mar 25, 2018 at 7:03
  • @vibhor1997a, yes pretty sure – user5763634 Commented Mar 25, 2018 at 10:54
Add a ment  | 

3 Answers 3

Reset to default 5

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'); 

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,
  };
}
var util = require('util');
fs.writeFileSync('./data.json', util.inspect(obj) , 'utf-8');

Ref. Write objects into file with Node.js

发布评论

评论列表(0)

  1. 暂无评论