user938363
user938363

Reputation: 10350

dataValues has to be present after model name to retrieve its value

Here is code to retrieve of a ForTrade with join to Artwork and Viewer with sequelizeus 6.x:

let _bid = await ForTrade.findOne({
            where: {id:_id},
            include:[{
                model:Artwork,
                include: [{
                    model:Viewer,
                    attributes:[["wallet_address", "trader_address"]] 
                }]
            }]
        });
        console.log("_bid viewer in addressoftrader : ", _bid.artwork.viewer.dataValues.trader_address);  //this is the right format to retrieve trader_address

Here is the association of the model:

Artwork.belongsTo(Viewer, {foreignKey: 'uploader_id'});
  ForTrade.belongsTo(Artwork, {foreignKey: "artwork_id"});

_bid.artwork.viewer.dataValues.trader_address can retrieve the value of trader_address which is a string. But _bid.artwork.viewer.trader_address yields undefined. Why dataValues has to be added after viewer to retrieve viewer object?

Upvotes: 0

Views: 844

Answers (2)

electroid
electroid

Reputation: 661

You can simply add raw: true to your query parameters and then you will get data result instead of the model instance:

const bids = await ForTrade.findOne({
    where: {id:_id},
    include:[{
        model:Artwork,
        include: [{
              model:Viewer,
              attributes:[["wallet_address", "trader_address"]] 
        }]
    }],
    raw: true // to get results instead of the model instance
});

Inspired by that answer Get only dataValues from Sequelize ORM

Upvotes: 0

boc4life
boc4life

Reputation: 961

The value that is returned from your findOne() query is not a plain object, it is a Sequelize instance.

This Sequelize instance can be manipulated using Sequelize methods such as set(), increment(), decrement(), and save(). Very useful.

As you've seen, you can access the dataValues property of this object, but I suspect that this is considered unsafe. You can, however, turn this instance into a plain object by invoking the .toJSON() method or the .get() method.

Slight tangent: One of the reasons this concept isn't immediately apparent is that when you use something like Express, you can simply use the res.json() method, pass in the _bid variable, and it will be sent to the client as a plain object. The reason for this is because the Express .json() method seeks out a .toJSON() method on an object passed into it. Because of that, it will send the plain object rather than the Sequelize instance.

Upvotes: 1

Related Questions