I have 5 endpoint with 4 methods implemented. For GET, POST, DELETE all of them goes well. I don't understand why PUT method doesn't work. In my case, I need to update column first_name and last_name but it send me error like this:
{
"name": "SequelizeDatabaseError",
"parent": {
"length": 221,
"name": "error",
"severity": "ERROR",
"code": "42703",
"where": "PL/pgSQL function last_updated() line 3 at assignment",
"file": "d:\\pginstaller_13.auto\\postgres.windows-x64\\src\\pl\\plpgsql\\src\\pl_exec.c",
"line": "5170",
"routine": "exec_assign_value",
"sql": "UPDATE \"actors\" SET \"first_name\"=$1,\"last_name\"=$2,\"updatedAt\"=$3 WHERE \"actor_id\" = $4",
"parameters": [
"Anne ",
"Anne",
"2020-10-29 02:54:11.642 +00:00",
"200"
]
},
"original": {
"length": 221,
"name": "error",
"severity": "ERROR",
"code": "42703",
"where": "PL/pgSQL function last_updated() line 3 at assignment",
"file": "d:\\pginstaller_13.auto\\postgres.windows-x64\\src\\pl\\plpgsql\\src\\pl_exec.c",
"line": "5170",
"routine": "exec_assign_value",
"sql": "UPDATE \"actors\" SET \"first_name\"=$1,\"last_name\"=$2,\"updatedAt\"=$3 WHERE \"actor_id\" = $4",
"parameters": [
"Anne ",
"Anne",
"2020-10-29 02:54:11.642 +00:00",
"200"
]
},
"sql": "UPDATE \"actors\" SET \"first_name\"=$1,\"last_name\"=$2,\"updatedAt\"=$3 WHERE \"actor_id\" = $4",
"parameters": [
"Anne ",
"Anne",
"2020-10-29 02:54:11.642 +00:00",
"200"
]
}
This is how i tested in Postman
And this is my models:
const actor = (sequelize, DataTypes) => {
const Actor = sequelize.define('actor', {
actor_id: {
type: DataTypes.INTEGER,
primaryKey: true,
unique: true,
autoIncrement: true,
allowNull: false,
},
first_name: {
type: DataTypes.STRING(45),
allowNull: false,
},
last_name: {
type: DataTypes.STRING(45),
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
},
updatedAt: {
type: DataTypes.DATE,
},
});
return Actor;
};
export default actor;
Help me, please. I have searched all around for the answer but still stuck.
UPDATE:
Here is my code when instantiate Sequelize:
import Sequelize from 'sequelize';
const sequelize = new Sequelize(
process.env.DATABASE,
process.env.DATABASE_USER,
process.env.DATABASE_PASSWORD,
{
dialect: 'postgres',
},
);
const models = {
Actor: sequelize.import('./actor'),
};
export { sequelize };
export default models;
And this is my app.js:
import 'dotenv/config';
import cors from 'cors';
import express from 'express';
import path from 'path';
import models, { sequelize } from './models';
import routes from './routes';
const app = express();
// Application-Level Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(async (req, res, next) => {
req.context = {
models,
me: await models.Actor,
};
next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
// Routes
app.get('/', async (req, res) => {
try {
res.render('index');
} catch (error) {
res.send(error);
}
});
app.use('/actor', routes.actor);
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// Start
sequelize.sync().then(async () => {
app.listen(process.env.PORT, () =>
console.log(`App listening on port ${process.env.PORT}!`),
);
});
module.exports = app;
Also, this is my actual table structure
[SOLVED]
This happen because I have deleted one column named "last_updated" that used as trigger when UPDATE, image . Now I disable that trigger and can successfully update.
My mistake, this DB I import from here and didn't give attention to it
Related
I am creating a simple CRUD API using Nodejs, express. I need to use postgresql hosted on heroku for this app and Sequelize as ORM. However interaction with database is not working.
Here is my code
index.js
const express = require('express')
require('dotenv').config()
const Sequelize = require('sequelize')
const usersRouter = require('./routers/users')
const sequelize = new Sequelize(process.env.DATABASE_URL, {
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false
}
}
})
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.')
})
.catch((err) => {
console.error('Unable to connect to the database:', err)
})
const app = express()
const bodyParser = require('body-parser')
const cors = require('cors')
app.use(cors())
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
const port = 3000
app.get('/', (req, res) => {
res.send('Nodejs mentoring 2022!')
})
app.use('/users', usersRouter)
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
/router/users
const express = require('express')
const router = express.Router()
connst {
getAllUsers
} = require('./controllers/userControllers')
//user routes
router
.route('/')
.get(getAllUsers)
module.exports = router
userControllers
const { Sequelize } = require('sequelize')
const sequelize = new Sequelize(process.env.DATABASE_URL, {
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false
}
}
})
const User = require('./../../models/user')(sequelize)
const createError = require('http-errors')
exports.getAllUsers = async (req, res, next) => {
try {
const users = await User.findAll()
if (!users) throw new createError.NotFound()
res.status(200).send(users)
} catch (e) {
next(e)
}
}
models/user
const { DataTypes } = require('sequelize')
module.exports = (sequelize) => {
const User = sequelize.define(
'User',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
allowNull: false
},
login: {
type: DataTypes.STRING,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
},
age: {
type: DataTypes.INTEGER,
allowNull: false
},
is_deleted: {
type: DataTypes.BOOLEAN,
allowNull: false
}
},
{
timestamps: false
}
)
return User
}
package.json
{
"name": "nodejs-mentoring-2022",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mamuna36/nodejs-mentoring-2022.git"
},
"author": "",
"license": "ISC",
"engines" : {
"node": "16.14.2"
},
"bugs": {
"url": "https://github.com/mamuna36/nodejs-mentoring-2022/issues"
},
"homepage": "https://github.com/mamuna36/nodejs-mentoring-2022#readme",
"devDependencies": {
"nodemon": "^2.0.20"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-joi-validation": "^5.0.1",
"joi": "^17.6.3",
"pg": "^8.8.0",
"sequelize": "^6.25.3",
"sqlite3": "^5.1.2"
}
}
when I try to test the getAllUsers endpoint in postman I get this error
Executing (default): SELECT "id", "login", "password", "age", "is_deleted" FROM "Users" AS "User";
Error
at Query.run (C:\Users\Mamuna_Anwar\VScodeProjects\nodejs-mentoring- 2022\node_modules\sequelize\lib\dialects\postgres\query.js:50:25)
at C:\Users\Mamuna_Anwar\VScodeProjects\nodejs-mentoring-2022\node_modules\sequelize\lib\sequelize.js:314:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async PostgresQueryInterface.select (C:\Users\Mamuna_Anwar\VScodeProjects\nodejs-mentoring-2022\node_modules\sequelize\lib\dialects\abstract\query-interface.js:407:12)
at async Function.findAll (C:\Users\Mamuna_Anwar\VScodeProjects\nodejs-mentoring-2022\node_modules\sequelize\lib\model.js:1134:21)
at async exports.getAllUsers (C:\Users\Mamuna_Anwar\VScodeProjects\nodejs-mentoring-2022\routers\controllers\userControllers.js:39:19)
Trying to learn sequelize, so I created a small test table and API. I am able to connect to the database and GET data from the API, but I can not insert anything. Sequelize is giving a warning that the value can't be null, even though I'm passing it in.
Call:
{payload=INSERT INTO api.testertab(submission_id, notes) VALUES (6452453223, 'testmessage2');, method=POST}
Basic Table Model:
const getTestertabModel = (sequelize, { DataTypes }) => {
const TT_ret = sequelize.define('testertab', {
submission_id: {
type: DataTypes.TEXT,
allowNull: false,
primaryKey: true
},
notes: {
type: DataTypes.TEXT,
allowNull: true
}
}, {
sequelize,
tableName: 'testertab',
schema: 'api',
timestamps: false,
indexes: [
{
name: "testertab_pkey",
unique: false,
fields: [
{ name: "submission_id" },
]
},
]
});
return TT_ret;
};
export default getTestertabModel;
and routes:
import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => {
console.log("get all")
const resp = await req.context.models.TT_ret.findAll()
return res.status(200).send(resp);
});
router.post('/upload', async (req, res) => {
console.log("post sub id")
//console.log(req.body)
const resp = await req.context.models.TT_ret.create();
return res.send(resp);
});
export default router;
index.js
import cors from 'cors';
import express from 'express';
import bodyParser from 'body-parser';
import models, { sequelize } from './src/models/index.js';
import routes from './src/routes/index.js';
const app = express();
import dotenv from 'dotenv/config';
app.use(bodyParser.json());
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/tab', routes.tester);
app.listen(process.env.port, () =>
console.log(`Example app listening on port ${process.env.port}!`),
);
Error message:
/root/node_modules/sequelize/lib/instance-validator.js:50
throw new sequelizeError.ValidationError(null, this.errors);
^
ValidationError [SequelizeValidationError]: notNull Violation: testertab.submission_id cannot be null
at InstanceValidator._validate (/root/node_modules/sequelize/lib/instance-validator.js:50:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async InstanceValidator._validateAndRunHooks (/root/node_modules/sequelize/lib/instance-validator.js:60:7)
at async InstanceValidator.validate (/root/node_modules/sequelize/lib/instance-validator.js:54:12)
at async model.save (/root/node_modules/sequelize/lib/model.js:2368:7)
at async Function.create (/root/node_modules/sequelize/lib/model.js:1344:12)
at async file:///root/easton_seqdb_api/src/routes/tester.js:14:16 {
errors: [
ValidationErrorItem {
message: 'testertab.submission_id cannot be null',
type: 'notNull Violation',
path: 'submission_id',
value: null,
origin: 'CORE',
instance: testertab {
dataValues: { submission_id: null },
_previousDataValues: {},
uniqno: 1,
_changed: Set(0) {},
_options: {
isNewRecord: true,
_schema: 'api',
_schemaDelimiter: '',
attributes: undefined,
include: undefined,
raw: undefined,
silent: undefined
},
isNewRecord: true
},
validatorKey: 'is_null',
validatorName: null,
validatorArgs: []
}
]
}
I have an Angular app w/ a proxy that's working well in local. There's one route that utilizes it with a Node API call.
Node.js
const express = require('express');
const api_service = require('./apiService');
const app = express();
app.get('/getData/:date', (req, res) => {
const date = req.params.date;
api_service.fetchData(...)
.then(response => {
res.json(response)
})
.catch(error => {
res.send(error)
})
})
app.listen(3000, () => {
console.log("Server started in port 3000!");
});
Function in my Angular Service:
fetchData(date: string) {
const requestOptions: Object = {
responseType: 'text',
};
this._http
.get<string>('/api/getData/' + date)
.pipe(
map((data) => {
this.result = data;
})
)
.subscribe((data) => {
this.mediaSource.next(this.result);
if (Object.keys(this.result).length != 0) {
this.history.push(this.result);
}
});
}
proxy-prod.config.json
{
"/api/*": {
"target": "https://example.com",
"secure": false,
"changeOrigin": true,
"logLevel": "debug",
"pathRewrite": { "^/api": "" }
}
}
proxy-local.conf.json
{
"/api/*": {
"target": "http://localhost:3000",
"pathRewrite": {
"^/api": ""
},
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
}
angular.json
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ui-dev:build",
"proxyConfig": "proxy-local.conf.json"
},
"configurations": {
"production": {
"browserTarget": "ui-dev:build:production",
"proxyConfig": "proxy-prod.config.json"
}
}
},
ng serve works perfectly.
ng serve --prod and ng build --aot --prod --output-hashing none do not.
The error I'm getting is:
headers: d, status: 200, statusText: 'OK', url: 'myexample.com', ok: false
I've tried this in my request but they cause errors too:
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
{ headers, responseType: 'text'}
Been searching, testing, and dissecting code for many hours and not sure how to proceed. Can you anyone assist?
Thanks
It's been seriously 10 days since i'm trying to deploy my web app online. i've gone back and forth between heroku and digital ocean. nothing solved. i've asked questions here all i get is a long post with technical terms i' not able to understand. Here's my problem :
i have a nuxt app with express.js in the backend and mongodb as the database. At first i had trouble with configuring host and port for my nuxt app. once i fixed it, anoither problem appeared : i'm not receiving data from the database. i don't if it's something related to database connection or with the express api configuration.
here's my nuxt config
export default {
ssr: false,
head: {
titleTemplate: 'Lokazz',
title: 'Lokazz',
meta: [
{ charset: 'utf-8' },
{
name: 'viewport',
content: 'width=device-width, initial-scale=1'
},
{
hid: 'description',
name: 'description',
content:
'Lokazz'
}
],
link: [
{
rel: 'stylesheet',
href:
'https://fonts.googleapis.com/css?family=Work+Sans:300,400,500,600,700&subset=latin-ext'
}
]
},
css: [
'swiper/dist/css/swiper.css',
'~/static/fonts/Linearicons/Font/demo-files/demo.css',
'~/static/fonts/font-awesome/css/font-awesome.css',
'~/static/css/bootstrap.min.css',
'~/assets/scss/style.scss'
],
plugins: [
{ src: '~plugins/vueliate.js', ssr: false },
{ src: '~/plugins/swiper-plugin.js', ssr: false },
{ src: '~/plugins/vue-notification.js', ssr: false },
{ src: '~/plugins/axios.js'},
{ src: '~/plugins/lazyLoad.js', ssr: false },
{ src: '~/plugins/mask.js', ssr: false },
{ src: '~/plugins/toastr.js', ssr: false },
],
buildModules: [
'#nuxtjs/vuetify',
'#nuxtjs/style-resources',
'cookie-universal-nuxt'
],
styleResources: {
scss: './assets/scss/env.scss'
},
modules: ['#nuxtjs/axios', 'nuxt-i18n','vue-sweetalert2/nuxt', '#nuxtjs/auth-next', "bootstrap-vue/nuxt"],
bootstrapVue: {
bootstrapCSS: false, // here you can disable automatic bootstrapCSS in case you are loading it yourself using sass
bootstrapVueCSS: false, // CSS that is specific to bootstrapVue components can also be disabled. That way you won't load css for modules that you don't use
},
i18n: {
locales: [
{ code: 'en', file: 'en.json' },
],
strategy: 'no_prefix',
fallbackLocale: 'en',
lazy: true,
defaultLocale: 'en',
langDir: 'lang/locales/'
},
router: {
linkActiveClass: '',
linkExactActiveClass: 'active',
},
server: {
port: 8080, // default: 3000
host: '0.0.0.0' // default: localhost
},
auth: {
strategies: {
local: {
token: {
property: "token",
global: true,
},
redirect: {
"login": "/account/login",
"logout": "/",
"home": "/page/ajouter-produit",
"callback": false
},
endpoints: {
login: { url: "/login", method: "post" },
logout: false, // we don't have an endpoint for our logout in our API and we just remove the token from localstorage
user:false
}
}
}
},
};
here's my package.json
{
"name": "martfury_vue",
"version": "1.3.0",
"description": "Martfury - Multi-purpose Ecomerce template with vuejs",
"author": "nouthemes",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"config": {
"nuxt": {
"host": "0.0.0.0",
"port": "8080"
}
},
}
here's my repository.js file
import Cookies from 'js-cookie';
import axios from 'axios';
const token = Cookies.get('id_token');
const baseDomain = 'https://lokazzfullapp-8t7ec.ondigitalocean.app';
export const customHeaders = {
'Content-Type': 'application/json',
Accept: 'application/json'
};
export const baseUrl = `${baseDomain}`;
export default axios.create({
baseUrl,
headers: customHeaders
});
export const serializeQuery = query => {
return Object.keys(query)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
.join('&');
};
an example of an api call i make locally that works without a problem :
import Repository, { serializeQuery } from '~/repositories/Repository.js';
import { baseUrl } from '~/repositories/Repository';
import axios from 'axios'
const url = baseUrl;
export const actions = {
async getProducts({ commit }, payload) {
const reponse = await axios.get(url)
.then(response => {
commit('setProducts', response.data);
return response.data;
})
.catch(error => ({ error: JSON.stringify(error) }));
return reponse;
},
}
here's my index.js (express file)
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose')
const cors = require('cors');
//const url = 'mongodb://localhost:27017/lokazz'
const url = 'mongodb+srv://lokazz:zaki123456#cluster0.hsd8d.mongodb.net/lokazz?retryWrites=true&w=majority'
const jwt = require('jsonwebtoken')
const con = mongoose.connection
mongoose.connect(url, {useNewUrlParser:true}).then(()=>{
const app = express();
// middlleware
app.use(express.json())
app.use(cors());
//products routes
const products = require('./product/product.router');
app.use('/', products)
//users routes
const users = require('./user/user.router');
app.use('/', users)
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
}).catch(error => console.log(error.reason));
con.on('open', () => {
console.log('connected...')
})
My directory structure
the error i get after the api request, meaning it's not receving any data.
ebd1ecd.js:2 TypeError: Cannot read properties of undefined (reading 'username')
at f.<anonymous> (c88240c.js:1)
at f.t._render (ebd1ecd.js:2)
at f.r (ebd1ecd.js:2)
at wn.get (ebd1ecd.js:2)
at new wn (ebd1ecd.js:2)
at t (ebd1ecd.js:2)
at f.In.$mount (ebd1ecd.js:2)
at init (ebd1ecd.js:2)
at ebd1ecd.js:2
at v (ebd1ecd.js:2)
idk if it's a problem with mongodb connection cluster or the api call.
This is the first time I'm using sequelize and i ran into a problem with creating a table in PostgreSQL. Server is running without any errors but its seems that sequelize don't do anything. I post my code below in hope that you can help me with this problem.
This is my server.js file
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(bodyParser.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// database
const db = require("./app/models");
const Role = db.role;
// db.sequelize.sync();
// force: true will drop the table if it already exists
db.sequelize.sync({force: true}).then(() => {
console.log('Drop and Resync Database with { force: true }');
initial();
});
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to bezkoder application." });
});
// routes
require('./app/routes/auth.routes')(app);
require('./app/routes/user.routes')(app);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
function initial() {
Role.create({
id: 1,
naziv: "user"
});
Role.create({
id: 2,
naziv: "moderator"
});
Role.create({
id: 3,
naziv: "admin"
});
}
my db.config
module.exports = {
HOST: "localhost",
USER: "postgres",
PASSWORD: "sarke",
DB: "elposlovanje",
dialect: "postgres",
port: 5432,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
};
my index.js from models
const config = require("../config/db.config.js");
const Sequelize = require("sequelize");
const sequelize = new Sequelize(
config.DB,
config.USER,
config.PASSWORD,
{
host: config.HOST,
dialect: config.dialect,
port: config.port,
pool: {
max: config.pool.max,
min: config.pool.min,
acquire: config.pool.acquire,
idle: config.pool.idle
}
}
);
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.user = require("../models/user.model.js")(sequelize, Sequelize);
db.role = require("../models/role.model.js")(sequelize, Sequelize);
db.role.belongsToMany(db.user, {
through: "user_roles",
foreignKey: "roleId",
otherKey: "userId"
});
db.user.belongsToMany(db.role, {
through: "user_roles",
foreignKey: "userId",
otherKey: "roleId"
});
db.ROLES = ["user", "admin", "moderator"];
module.exports = db;
role from models
module.exports = (sequelize, Sequelize) => {
const Role = sequelize.define("roles", {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
naziv: {
type: Sequelize.STRING
}
});
return Role;
};
and user from model
module.exports = (sequelize, Sequelize) => {
const User = sequelize.define("users", {
ime: {
type: Sequelize.STRING
},
prezime: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
lozinka: {
type: Sequelize.STRING
},
brojindexa: {
type: Sequelize.STRING
}
});
return User;
};
Output after running node server.js is
Server is running on port 8080.
my package.json
{
"name": "node-js-jwt-auth-postgresql",
"version": "1.0.0",
"description": "Node.js Demo for JWT Authentication with PostgreSQL",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"node js",
"express",
"jwt",
"authentication",
"postgresql"
],
"author": "bezkoder",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"pg": "^7.18.2",
"pg-hstore": "^2.3.3",
"sequelize": "^5.22.3"
},
"devDependencies": {
"sequelize-cli": "^6.2.0"
}
}
i found out the problem was in the version of pg