I am new to sequelize and node js. I have been trying to implement Sequelize Many-to-Many Association using node.js, express with PostgreSQL database following this tutorial. I have implemented a single table and retrieve data correctly without any issue. But in many-to-many relationships, I can only print data to console and in postman and chrome, it keeps loading around a minute and wait without loading data. Here are my code files.
db config file
const dbConfig = require("../config/db.config.js");
const Sequelize = require("sequelize");
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.dialect,
operatorsAliases: false,
define: {
timestamps: true,
freezeTableName: true
},
pool: {
max: dbConfig.pool.max,
min: dbConfig.pool.min,
acquire: dbConfig.pool.acquire,
idle: dbConfig.pool.idle
}
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.actor = require("./actor.model.js")(sequelize, Sequelize);
db.film = require("./film.model.js")(sequelize, Sequelize);
db.film_actor = require("./film_actor.model.js")(sequelize, Sequelize);
db.film.belongsToMany(db.actor, {
through: db.film_actor,
as: "actors",
foreignKey: "film_id",
});
db.actor.belongsToMany(db.film, {
through: db.film_actor,
as: "films",
foreignKey: "actor_id",
});
module.exports = db;
filmController file
const db = require("../models");
const Film = db.film;
const Actor = db.actor;
//find all films including actors
exports.findAll = () => {
return Film.findAll({
include: [
{
model: Actor,
as: "actors",
attributes: ["first_name", "last_name"],
through: {
attributes: [],
}
},
],
})
.then((film) => {
console.log(film[5]);
return film;
})
.catch((err) => {
console.log(">> Error while retrieving films: ", err);
});
};
// find film by film id
exports.findById = (req, res) => {
const film_id = req.params.id;
return Film.findByPk(film_id, {
include: [
{
model: Actor,
as: "actors",
attributes: ["first_name", "last_name"],
through: {
attributes: [],
}
},
],
})
.then((films) => {
return films;
})
.catch((err) => {
console.log(">> Error while finding film: ", err);
});
};
film.route file
module.exports = app => {
const film = require("../controllers/film.controller.js");
var router = require("express").Router();
// Retrieve all films
router.get("/films", film.findAll);
// Retrieve a single actor with id
router.get("/films/:id", film.findById);
app.use('/api', router);
};
server.js file
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const filmController = require("./app/controllers/film.controller");
const app = express();
const db = require("./app/models");
db.sequelize.sync();
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to bezkoder application." });
});
db.sequelize.sync().then(() => {
// run();
});
require("./app/routes/actor.routes")(app);
require("./app/routes/film.routes")(app);
// app.get('/films',filmController.findAll);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
As per my understanding, the issue should be about the routing. I created route for many to many associations as the same way I did for singe table(actor) but this problem occurred. I put a console log under findAll() method in filCcontroller and it prints the data in the console along with the query.
This is the output on my console
Executing (default): SELECT "film"."film_id", "film"."title", "film"."description", "film"."release_year", "film"."language_id", "film"."rental_duration", "film"."length", "actors"."actor_id" AS "actors.actor_id", "actors"."first_name" AS "actors.first_name", "actors"."last_name" AS "actors.last_name" FROM "film" AS "film" LEFT OUTER JOIN ( "film_actor" AS "actors->film_actor" INNER JOIN "actor" AS "actors" ON
"actors"."actor_id" = "actors->film_actor"."actor_id") ON "film"."film_id" = "actors->film_actor"."film_id";
film {
dataValues: {
film_id: 166,
title: 'Color Philadelphia',
description: 'A Thoughtful Panorama of a Car And a Crocodile who must Sink a Monkey in The Sahara Desert',
release_year: 2006,
language_id: 1,
rental_duration: 6,
length: 149,
actors: [
[actor], [actor],
[actor], [actor],
[actor], [actor],
[actor]
]
},
_previousDataValues: {
film_id: 166,
title: 'Color Philadelphia',
description: 'A Thoughtful Panorama of a Car And a Crocodile who must Sink a Monkey in The Sahara Desert',
release_year: 2006,
language_id: 1,
rental_duration: 6,
length: 149,
actors: [
[actor], [actor],
[actor], [actor],
[actor], [actor],
[actor]
]
},
_changed: Set {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [ [Object] ],
includeNames: [ 'actors' ],
includeMap: { actors: [Object] },
includeValidated: true,
attributes: [
'film_id',
'title',
'description',
'release_year',
'language_id',
'rental_duration',
'length'
],
raw: true
},
isNewRecord: false,
actors: [
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
},
actor {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set {},
_options: [Object],
isNewRecord: false
}
]
}
any help would be greatly appreciated.