Home > database >  NodeJS PostgreSQL Express SequelizeEagerLoadingError on relationship table
NodeJS PostgreSQL Express SequelizeEagerLoadingError on relationship table

Time:11-28

I'm having a trouble where I couldn't access the relationship data table from NodeJS PostgreSQL and Express.

First of all here is my simple table :

enter image description here

As you can see, my "jenis" table has association with "kategori" table, one jenis can have multiple kategori, and one kategori should only contain one jenis.

Here is my migration on Postgres Sequelize :

jenis-migration.js

"use strict";
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable("Umkm_Jenis", {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      nama: {
        type: Sequelize.STRING,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("Umkm_Jenis");
  },
};
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

kategori-migration.js

"use strict";
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable("Umkm_Kategori", {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      jenis_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
      },
      nama: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("Umkm_Kategori");
  },
};
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

jenis.model.js

"use strict";
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
  class Umkm_Jenis extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      this.hasMany(models.Umkm_Kategori, {
        foreignKey: "jenis_id",
        as: "umkm_kategori",
      });
    }
  }
  Umkm_Jenis.init(
    {
      nama: DataTypes.STRING,
    },
    {
      sequelize,
      modelName: "Umkm_Jenis",
      freezeTableName: true,
    }
  );
  return Umkm_Jenis;
};
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

kategori-model.js

"use strict";
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
  class Umkm_Kategori extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      this.belongsTo(models.Umkm_Jenis, {
        foreignKey: "jenis_id",
        as: "umkm_jenis",
      });
    }
  }
  Umkm_Kategori.init(
    {
      jenis_id: DataTypes.INTEGER,
      nama: DataTypes.STRING,
    },
    {
      sequelize,
      modelName: "Umkm_Kategori",
      freezeTableName: true,
    }
  );
  return Umkm_Kategori;
};
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I have created some seeder data on postgres for both jenis and kategori table.

Now I want my getAllKategori API to actually include the value from "jenis" table using the relationship that I have made. Below is my apiController for kategori :

exports.findAllKategori = async (req, res) => {
  //check if theres a filter applied
  const nama = req.query.nama;
  const condition = nama ? { nama: { [Op.iLike]: `%${nama}%` } } : null;

  try {
    const response = Kategori.findAll({
      where: condition,
      include: [{ model: db.jenis, as: "umkm_jenis", required: false }],
    });
    const data = await response;
    return res.status(200).send(data);
  } catch (error) {
    console.log(error);
    return res.status(500).send(error);
  }
};
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

But when I tried to hit the API from POSTMAN, it shows SequelizeEagerLoadingError.

enter image description here

If I commented this line on kategoriController :

  include: [{ model: db.jenis, as: "umkm_jenis", required: false }],

and then try to hit the api once more, it successfully shows all my data.

enter image description here

I have already read some similar question in this forum but none of it seems to work.

Thank you for taking your time!

UPDATE

Below is the models/index.js file

"use strict";

const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || "development";
const config = require(__dirname   "/../config/config.json")[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(
    config.database,
    config.username,
    config.password,
    config
  );
}

fs.readdirSync(__dirname)
  .filter((file) => {
    return (
      file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
    );
  })
  .forEach((file) => {
    const model = require(path.join(__dirname, file))(
      sequelize,
      Sequelize.DataTypes
    );
    db[model.name] = model;
  });

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

db.kategori = require("./umkm_kategori")(sequelize, Sequelize);
db.jenis = require("./umkm_jenis")(sequelize, Sequelize);
db.produk = require("./umkm_produk")(sequelize, Sequelize);
db.review = require("./umkm_review")(sequelize, Sequelize);

module.exports = db;
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

console.log(error) enter image description here

CodePudding user response:

You already registered all models and associations with this code pieces:

const model = require(path.join(__dirname, file))(
      sequelize,
      Sequelize.DataTypes
    );
    db[model.name] = model;

and

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

so this code is registering models once again, just remove it and use model names defined above.

db.kategori = require("./umkm_kategori")(sequelize, Sequelize);
db.jenis = require("./umkm_jenis")(sequelize, Sequelize);
db.produk = require("./umkm_produk")(sequelize, Sequelize);
db.review = require("./umkm_review")(sequelize, Sequelize);
  • Related