1

Why when I use JSON.stringify in node.js on data from database request I get objects with the data itself, and if I use console.log I get a lot of additional parameters like dataValues, _previousDataValues, _modelOptions.... I use sequelize.js

console.log(JSON.stringify(data,'',2))

{
  id:1
}

console.log(data)

Kindergarten_data {
  dataValues:
    { id: 1}
 _changed: {},
  _modelOptions:
   { timestamps: true,
     validate: {},
     freezeTableName: true,
     underscored: false,
     underscoredAll: false,
     paranoid: false,
     rejectOnEmpty: false,
     whereCollection: null,
     schema: null,
     schemaDelimiter: '',
     defaultScope: {},
     scopes: [],
     indexes: [],...
2
  • And what's the problem? You're using sequelize, it returns you models, e.g. objects with data, methods, hooks etc. Commented Apr 4, 2019 at 10:36
  • I want to know why JSON.stringify shows only data values from database . Why not full object? Why JSON.stringify ignore _previousDataValues, _modelOptions.... Commented Apr 4, 2019 at 10:39

2 Answers 2

3

JSON.stringify() has a protocol which it follows:

JSON.stringify() converts a value to JSON notation representing it:

  • If the value has a toJSON() method, it's responsible to define what data will be serialized.
  • Boolean, Number, and String objects are converted to the corresponding primitive values during stringification, in accord with the traditional conversion semantics.
  • [...]

It is pretty obvious that your stringified stuff simply does not follow what you see with console.log(), since you would have to see { dataValues: {id: 1} ..., but you see {id: 1} instead. So it is not about some mystical "JSON-representability" other answers may suggest, but sequelize.js simply provides toJSON() method, and thus it JSON-exports only your data, not the entire infrastructure.

The method is here: https://github.com/sequelize/sequelize/blob/master/lib/model.js#L4226

toJSON() {
  return _.cloneDeep(
    this.get({
      plain: true
    })
  );
}

The get() it refers is here: https://github.com/sequelize/sequelize/blob/master/lib/model.js#L3313

get(key, options) {
  if (options === undefined && typeof key === 'object') {
    options = key;
    key = undefined;
  }

  [...]

  if (key) {
    [...]
  }

  return this.dataValues;
}

cloneDeep() just makes a copy of the thing, it does not matter here.
What matters is the return this.dataValues; above. That is the line which strips the object you see in the console, and results in serializing only its dataValues field.

Small-scale demo:

var data1={
  dataValues:{id:1},
  somethingElse:[1,2,3],
  _stuff:{a:'b'}
};

var data2={
  dataValues:{id:1},
  somethingElse:[1,2,3],
  _stuff:{a:'b'},
  toJSON:function(){return this.dataValues;}
};

console.log("data1:",JSON.stringify(data1));
console.log("data2:",JSON.stringify(data2));

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

Comments

-1

JSON.stringify() returns JSON-safe string representation of its input(eg JS object). It will strip off all properties/fields which doesn't have an equivalent JSON representation. Whereas console.log() outputs the JS object as it is to the console.

1 Comment

You answer is incomplete. For example, _modelOptions (from example) does have JSON representation. See answer from @tevemodar

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.