Closed aprilmintacpineda closed 7 years ago
I have figured out a solution for this.
@aprilmintacpineda I am also facing same issue. Can you please share your findings?
can't tell us how you solve this?
Hi, I'm having the same issue and I'm stuck with this for hours, I'd really appreciate if someone could share a solution. I'm working with latest versions of Electron, Sequelize, and ExpressJS
Right now I have my 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 = sequelize['import'](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
And my main server.js file
const express = require('express');
const bodyParser = require('body-parser');
// here the call to the sequelize models
const db = require('./database/models/index.js');
const app = express();
app.use(bodyParser.json());
app.get('/api/events', (req, res) => {
return db.Event.findAll()
.then((events) => res.send(events))
.catch((err) => {
console.log('There was an error querying events', JSON.stringify(err))
return res.send(err)
});
});
app.listen(3000, () => {
console.log('Server is up on port 3000');
});
Then i require the server.js right into the main electron js file (for me is background.js)
When i try to serve with electron, my server goes up and running, but everytime i try to http request the "/api/events/" get, I keep getting this:
TypeError: Cannot read property 'findAll' of undefined
Because it doesn't find my "Event" model, I am guessing cause it doesn't loop correctly throu the models js files since I don't see them anywhere in the dist builded folder. Note: when I try to run the server straight with
node src/server.js
Everything works fine... It's like Electron doesn't deal well with Sequelize models.
problem is with this code
fs .readdirSync(__dirname) .filter(file => { return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); }) .forEach(file => { const model = sequelize['import'](path.join(__dirname, file)); db[model.name] = model; });
When you create a build it can not find any file that is why Event
is not found.
You have to hardcore require the model in case of electron above code is okay only if this runs in nodejs
@lysla Below is just a logic, you can refactor / change, I did same time ago and its working that time
index.js
import Sequelize from 'sequelize';
import { sequelize, config } from '../config/DatabaseConnection';
let models = {};
const DB = (function () {
if (Object.keys(models).length) {
return models;
}
let modules = [
require('./categoryModel'),
require('./conditionModel'),
];
// Initialize models
modules.forEach((module) => {
const model = module(sequelize, Sequelize, config);
models[model.name] = model;
});
// Apply associations
Object.keys(models).forEach((key) => {
if ('associate' in models[key]) {
models[key].associate(models);
}
});
models.sequelize = sequelize;
models.Sequelize = Sequelize;
return models;
})();
module.exports = DB;
`
use like
import DB from '../models';
DB.category.findById(id, {......}
@cashwani Oh my, I'm really thankful. That managed to make it work, thank you so much! ❤ For clarity, that's how my index.js files look now:
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
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);
}
let models = {};
const db = (function () {
if (Object.keys(models).length) {
return models;
}
let modules = [
require('./event')
];
modules.forEach((module) => {
const model = module(sequelize, Sequelize, config);
models[model.name] = model;
});
Object.keys(models).forEach((key) => {
if ('associate' in models[key]) {
models[key].associate(models);
}
});
models.sequelize = sequelize;
models.Sequelize = Sequelize;
return models;
})();
module.exports = db;
I don't want to run too much offtopic, but I was wondering if the way I am using expressjs inside electron is proper. I mean, it works, but I'm unsure its the best way. Resuming, I have a server.js where I init my expressjs server that function like a local api, interacting to a local sqlite3 database via sequelize. I just put a
require('./server')
inside of the main electron js file (the one that holds the 'createWindow'). Nothing else. Is that right? Feels casual 🤔
Here is how i would do this, much cleaner approach.
const {db} = require('../config');
const Sequelize = require('sequelize');
const fs = require('fs');
const async = require('async');
let sequelize = new Sequelize(db.database, db.user, db.password, {
host: db.host || 'localhost',
dialect: 'mysql',
logging: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false
});
let db = {};
// Read the models directory to load all models
fs.readdir("./models", (errs, files) => {
async.forEach(files, (item, cb) => {
const ModelName = item.replace('.js', '');
db[ModelName] = require('./models/' + item)(sequelize);
cb();
}, async () => {
try {
await sequelize.sync({alter: true});
} catch (e) {
console.log('error while sequelize sync');
}
});
});
module.exports = db;
My Model Look like this: user.js
const Sequelize = require("sequelize");
module.exports = (sequalize) => {
return sequalize.define('user', {
first_name: Sequelize.STRING,
last_name: Sequelize.STRING,
email: Sequelize.STRING,
password: Sequelize.STRING,
createdAt: {
type: Sequelize.DATE,
allowNull: true
},
updatedAt: {
type: Sequelize.DATE,
allowNull: true
},
});
};
Here is how i would do this with sqlite database models/index.js
'use strict'
const fs = require('fs')
const path = require('path')
const Sequelize = require('sequelize')
const basename = path.basename(__filename)
const environment = process.env.NODE_ENV || 'development'
const config = require(`${__dirname}/../config/config.json`)[environment]
const database = {}
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) => {
var model = sequelize['import'](path.resolve(__dirname, file));
database[model.name] = model
})
for (var modelName in database) {
if (database[modelName].associate) {
database[modelName].associate(database);
}
}
database.sequelize = sequelize
database.Sequelize = Sequelize
module.exports = database
My Model look like this : masterunit.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const MasterUnit = sequelize.define('MasterUnit', {
id: {
type:DataTypes.INTEGER,
primaryKey: true
},
unit: DataTypes.STRING,
level: DataTypes.STRING
}, {});
MasterUnit.associate = function(models) {
// associations can be defined here
};
return MasterUnit;
}
and My config/config.json
{
"development": {
"dialect": "sqlite",
"storage": "./.temp/database.db"
},
"test": {
"dialect": "sqlite",
"storage": ":memory"
},
"production": {
"dialect": "sqlite",
"storage": "./.temp/database.db"
}
}
I use the same approach. I use sequelize with Electron, the problem is, when I package my app, it throws an error saying that models directory is not defined. How do you handle that?
Theoretically, I am thinking that if I simply import them and attach them to
db
it should work, but I actually have to usesequelize['import']()
for that do I? since I bundle all my files I should just import all my models then attach them todb
.