0

Why i can access the property inside dataValues without accessing dataValues property?

Example:

const data = await Product.findAll({
    attributes: ['id', 'name', 'price', 'stock', 'sku']
});

console.log(data);

Result of console.log(data):

[
  Product {
    dataValues: {
      id: 1,
      name: 'Samsung Galaxy A53',
      price: 5000000,
      stock: 100,
      sku: 'SM001'
    },
    _previousDataValues: {
      id: 1,
      name: 'Samsung Galaxy A53',
      price: 5000000,
      stock: 100,
      sku: 'SM001'
    },
    uniqno: 1,
    _changed: Set(0) {},
    _options: {
      isNewRecord: false,
      _schema: null,
      _schemaDelimiter: '',
      raw: true,
      attributes: [Array]
    },
    isNewRecord: false
  },
  Product {
    dataValues: {
      id: 2,
      name: 'Samsung Galaxy S22',
      price: 10000000,
      stock: 100,
      sku: 'SM002'
    },
    _previousDataValues: {
      id: 2,
      name: 'Samsung Galaxy S22',
      price: 10000000,
      stock: 100,
      sku: 'SM002'
    },
    uniqno: 1,
    _changed: Set(0) {},
    _options: {
      isNewRecord: false,
      _schema: null,
      _schemaDelimiter: '',
      raw: true,
      attributes: [Array]
    },
    isNewRecord: false
  }
]

I think if i want to get 'Samsung Galaxy A53', i must write a code like this:

console.log(data[0].dataValues.name) // it is works

But why i can get 'Samsung Galaxy A53' with a code like this?

console.log(data[0].name) // i can access directly to name property without using dataValues property
Artix
  • 1
  • 1
  • @Peterrabbit, but it is works bro, so i ask here because i'm confused why it is works... – Artix Jan 28 '23 at 17:50

2 Answers2

0

All Sequelize models are actually DAOs.
From the documentation:

A Model represents a table in the database. Instances of this class represent a database row.

Model instances operate with the concept of a dataValues property, which stores
the actual values represented by the instance.
By default, the values from dataValues can also be accessed directly from the Instance, that is:

instance.field
// is the same as
instance.get('field')
// is the same as
instance.getDataValue('field')

However, if getters and/or setters are defined for field they will be invoked,  
instead of returning the value from dataValues.
Accessing properties directly or using get is preferred for regular use,  
getDataValue should only be used for custom getters.

See Model section

Anatoly
  • 20,799
  • 3
  • 28
  • 42
  • Thank you so much for the answer. But how is it possible in javascript rules? i'm just curious – Artix Jan 28 '23 at 18:06
  • What do you mean by JS rules? By default a model has getters/settirs for all fields and uses `dataValues` to get/set the underlying values. This prop is handful when you need to have custom getters and/or setters for some fields you might need to get the underlying value - and this is the moment when `dataValues` starts to play its role. – Anatoly Jan 28 '23 at 18:36
  • Hello sir, i'm just curious, is property 'field' is stored under prototypes? because i can't see property `field` in console.log(instance). I only see property 'dataValues', '_previousDataValues', etc. Thankyou before – Artix Feb 27 '23 at 19:07
  • It depends on how Sequelize model provides a text representation of itself. Maybe this answer helps you to get it: https://stackoverflow.com/a/49461757/1376618 – Anatoly Feb 28 '23 at 20:11
  • Thank you so much sir, your answer very helpful. every time i use sequelize, that question is always on my mind. Thank you :) – Artix Mar 02 '23 at 10:03
0

You can't access the name by using data[0].name, because data[0].name doesn't exist.

As shown by your console.log(...), the first element of your array of objects, data[0], has these immediate properties:

  • dataValues,
  • _previousDataValues,
  • uniqno,
  • _changed,
  • _options, and
  • isNewRecord

The name is not a primary property, it's within the dataValues. That's why need to do data[0].dataValues.name or data[0]["dataValues"]["name"] to get it.

FiddlingAway
  • 1,598
  • 3
  • 14
  • 30