This is writing in both log file success and error.log if i called with log.fail I would expect it should write in error-date.log file. I don't know what's wrong here
const fs = require('fs');
var winston = require('winston');
const env = process.env.NODE_ENV;
const logDir = 'logs';
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir);
}
const now = new Date();
var logger = winston.createLogger({
transports: [
new (require('winston-daily-rotate-file'))({
filename: `${logDir}/success-%DATE%.log`,
timestamp: now,
datePattern: 'DD-MM-yyyy',
prepend: true,
json: false,
level: 'info',
}),
new (require('winston-daily-rotate-file'))({
filename: `${logDir}/error-%DATE%.log`,
timestamp: now,
datePattern: 'DD-MM-yyyy',
prepend: true,
json: false,
level: 'error',
}),
],
exitOnError: false,
});
const log = {
fail: function (ee) {
logger.error(`${now.toISOString()} - ${JSON.stringify(ee)}`);
},
success: function (ee) {
logger.info(`${now.toISOString()} - ${JSON.stringify(ee)}`);
},
};
module.exports = log;
Related
Im creating a MERN stack application and in the react front end, i intend to have a form to add a product, the form is going to have a lot of inputs including an image upload option. I want to know how to handle the image upload from the express side using Multer. i have used their documentation but im not sure whether the code i wrote is correct. I also haven't created the front end yet, so i am currently using postman to test the api. How do i test whether the image upload functionality is working using postman? I would be posting the code i have written so far for context.
Product model:
const mongoose = require('mongoose')
const ProductSchema = new mongoose.Schema({
name:{
type: String,
required: [true, 'please provide a product name'],
maxlength: 20,
minlength: 3
},
category: {
type: String,
required: [true, 'please provide a category'],
maxlength: 20,
minlength: 3
},
quantity: {
type: Number,
required: [true, 'please provide the quantity']
},
price: {
type: Number,
required: [true, 'please provide the price']
},
description: {
type: String,
required: [true, 'please provide the description'],
trim: true
},
image: {
type: String
},
createdBy: {
type: mongoose.Types.ObjectId,
ref: 'User',
required: [true, 'Please provide the user'],
}, },
{ timestamps: true } )
module.exports = mongoose.model('Product', ProductSchema)
file upload.js:
const multer = require('multer')
const { v4: uuidv4 } = require('uuid')
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, '../uploads')
},
filename: function(req, file, cb){
cb(null, uuidv4() + '-' + Date.now() + path.extname(file.originalname) )
}
})
const fileFilter = (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']
if(allowedTypes.includes(file.mimetype)) {
cb(null, true)
}else(
cb(null, false)
)
}
const upload = multer({storage, fileFilter})
module.exports = upload
Product router:
const express = require('express')
const router = express.Router()
const upload = require('../utils/fileUpload')
const {getAllProducts, createProduct, getProduct, updateProduct, deleteProduct} = require('../controllers/products')
router.route('/').post(upload.single('image'), createProduct).get(getAllProducts)
router.route('/:id').get(getProduct).patch(updateProduct).delete(deleteProduct)
module.exports = router
Product controller:
const Product = require('../models/Product')
const { StatusCodes } = require('http-status-codes')
const { BadRequestError, NotFoundError } = require('../errors')
const createProduct = async (req, res) => {
req.body.createdBy = req.user.userId
const product = await Product.create({...req.body, image: req.file})
res.send('create Product')
}
const getAllProducts = async (req, res) => {
res.send('get All products')
}
const getProduct = async (req, res) => {
res.send('get product')
}
const updateProduct = async (req, res) => {
res.send('update product')
}
const deleteProduct = async (req, res) => {
res.send('delete product')
}
module.exports = {
getAllProducts, createProduct, getProduct, updateProduct, deleteProduct
}
You can change the parameter type to file from postman to try uploading files when sending a request :
I apologize for something that could be very simple to fix, I just cannot figure it out. I've used this code in another project before with the exact same layout and that project works, but on this project, it's not working.
As seen below in the code, I am doing a simple findAll() query. The database is connected perfectly fine but I keep getting this error no matter what I try.
[Error is here][1]
I wanted to double-check to see if it's because of me or if it's an issue with the latest release of sequelize, but I doubt it because I haven't seen any issues like this pop up yet.
But if nobody can see an issue, I will submit a bug ticket.
root/routes/ShopItems.js
const express = require('express')
const router = express.Router()
const { ShopItems } = require('../models')
router.get('/', async(req, res) => {
const data = await ShopItems.findAll()
res.json(data)
})
module.exports = router
root/index.js
const express = require('express')
const session = require('express-session')
const app = express()
const cors = require('cors')
const db = require('./models')
const { SECRET, PORT } = require('./temp_secret')
app.use(express.json())
app.use(cors())
app.use(session({
secret: SECRET,
resave: true,
saveUninitialized: false,
}))
app.use(express.urlencoded({extended: false}))
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "X-Requested-With,GET,POST,content-type,Origin,Accept")
req.header("Access-Control-Allow-Origin", "*")
req.header("Access-Control-Allow-Headers", "X-Requested-With,GET,POST,content-type,Origin,Accept")
next()
})
// Routers
const ShopItemsRouter = require('./routes/ShopItems')
app.use('/shop', ShopItemsRouter)
db.sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Running on ${PORT}`)
})
})
root/models/index.js
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;
module.exports = db;
root/models/ShopItems.js
module.exports = (sequelize, DataTypes) => {
const ShopItems = sequelize.define('shop_items', {
item_name: {
type: DataTypes.STRING(),
allowNull: false
},
item_description: {
type: DataTypes.STRING(),
allowNull: false
},
item_type: {
type: DataTypes.STRING(),
allowNull: false,
defaultValue: 'Single Item'
},
item_categories: {
type: DataTypes.JSON(),
allowNull: false,
defaultValue: '{}'
},
item_genres: {
type: DataTypes.JSON(),
allowNull: false,
defaultValue: '{}'
},
initial_item_price: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
item_discount: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
item_price: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
number_of_sales: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
}
})
return ShopItems
}
Thank you anyone that helps, I greatly appreciate it.
[1]: https://i.stack.imgur.com/zBOTE.png
In the ShopItems routes file you have
const { ShopItems } = require('../models')
The problem with this is that the index.js file (Which is what gets brought in with the above statement), does not export a ShopItems property. This is why your error message is saying "Cannot read properties of undefined", because in this case the ShopItems variable is returning undefined.
Without seeing your ShopItems model I can't say for sure if this will work, but if that model exists and is set up properly, you should be able to do:
const db = require('../models')
And then inside of the route method:
const data = await db.ShopItems.findAll()
I am getting this error on Postman when I send request for uploading files on Feathersjs:
{
"name": "GeneralError",
"message": "ENOENT: no such file or directory, open 'public/uploads/pic'",
"code": 500,
"className": "general-error",
"data": {},
"errors": {}
}
My uploads.service.js:
const {Uploads} = require('./uploads.class');
const createModel = require('../../models/uploads.model');
const hooks = require('./uploads.hooks');
const multer = require('multer');
const storage = multer.diskStorage({
destination: (_req, _file, cb) => cb(null, 'public/uploads'), // where the files are being stored
filename: (_req, file, cb) => {
console.log(_req.body);
//cb(null, ${_req.body.name});
cb(null, `${_req.body.name}`); //
}, // getting the file name
});
const uploads = multer({
storage,
limits: {
fieldSize: 1e8,
fileSize: 1e7,
},
});
module.exports = function(app) {
const options = {
Model: createModel(app),
paginate: app.get('paginate'),
multi: true,
};
// Initialize our service with any options it requires
app.use(
'/uploads',
uploads.array('files'),
(req, _res, next) => {
const {method} = req;
if (method === 'POST' || method === 'PATCH') {
console.log(req.files);
console.log(req.body);
req.feathers.files = req.body.files;
const body = [];
for (const file of req.files)
body.push({
name: req.body.name,
newNameWithPath: file.path,
});
req.body = method === 'POST' ? body : body[0];
}
next();
},
new Uploads(options, app),
);
// Get our initialized service so that we can register hooks
const service = app.service('uploads');
service.hooks(hooks);
};
This is my uploads.model.js:
module.exports = function(app) {
const modelName = 'uploads';
const mongooseClient = app.get('mongooseClient');
const {Schema} = mongooseClient;
const schema = new Schema(
{
name: {type: String, required: true},
},
{
timestamps: true,
},
);
// This is necessary to avoid model compilation errors in watch mode
// see https://mongoosejs.com/docs/api/connection.html#connection_Connection-deleteModel
if (mongooseClient.modelNames().includes(modelName)) {
mongooseClient.deleteModel(modelName);
}
return mongooseClient.model(modelName, schema);
};
I really cannot figure out where exactly the problem is. According to me it is supposed to make the folder automatically when I upload the file.
I would really appreciate some help. Thank you in advance.
It was my own mistake. I made the uploads folder inside public folder myself and now it's working.
I have created an e2e test that will need to be downloaded outside of my local.
In config.js file
var path = require('path');
var downloadsPath = path.resolve(__dirname, './downloads');
capabilities: {
'browserName': process.env.BROWSER || 'chrome',
'chromeOptions': {
prefs: {
'download': {
'prompt_for_download': false,
'default_directory': 'downloadsPath',
},
},
},
},
In my e2e test file
it('view formulary download all mapped meds test', function() {
var mappedMedsFile = '/full_hospital_seeded_all_mapped_medications.csv';
adminPage.viewFormulary.click();
adminPage.downloadMappedMeds.click();
browser.wait(function() {
return fs.existsSync(mappedMedsFile);
}, 30000).then(function() {
md5File(mappedMedsFile, (err, hash) => {
if (err) throw err
})
expect(md5File.sync(mappedMedsFile)).toEqual(viewFormularyResults.expectMappedMedsHash)
});
});
I was expecting this file to download correctly, but instead, I get the following error:
- Failed: Wait timed out after 30001ms
I've been trying to send a cookie back to the client from the server. I get the response data but i don't see "set-cookie" in the response headers
My Apollo Server Configuration:
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req, connection, res }) => ({
dummyModels: dummyModels,
models: models,
req,
connection,
res,
currentUser: dummyModels.users[2],
dummyUsers: dummyModels.dummyUsers,
}),
});
app.use(cors({
credentials: true,
origin: 'http://localhost:3000',
// preflightContinue: true,
}));
My resolver:
login: async (parent, args, context) => {
const _include_headers = function(body, response, resolveWithFullResponse) {
return {'headers': response.headers, 'data': body};
};
const loginRequestOptions = {
method: 'POST',
uri: 'http://localhost:3000/incorta/authservice/login',
qs: {
// access_token: 'xxxxx xxxxx', // -> uri + '?access_token=xxxxx%20xxxxx'
user: args.input.username,
pass: args.input.password,
tenant: args.input.tenantName,
},
transform: _include_headers,
json: true // Automatically parses the JSON string in the response
};
const loginResponse = await request(loginRequestOptions);
console.log(loginResponse);
context.res.cookie(
'JSESSIONID',
tough.Cookie.parse(loginResponse.headers['set-cookie'][0]).value,
{
// expires : new Date(Date.now() + 9999999),
// path: '/incorta/',
// HttpOnly: false,
// maxAge: 1000 * 60 * 60 * 24 * 99, // 99 days
},
);
context.res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
return loginResponse.data;
},
Note: i'm using request-promise-native to make the request
My Apollo Client Configuration:
const httpLink = createHttpLink({
uri: 'http://172.16.16.130:4000/graphql',
credentials: 'include',
fetchOptions: {
credentials: 'include',
},
});
const wsLink = new WebSocketLink({
uri: 'ws://172.16.16.130:4000/graphql',
options: {
reconnect: true,
connectionParams: {
headers: {
'x-user-header': localStorage.getItem('userObject'),
},
},
}
});
const terminatingLink = split(
// split based on operation type
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink,
);
const link = ApolloLink.from([terminatingLink]);
const cache = new InMemoryCache();
export const client = new ApolloClient({
link,
cache,
});
I have tried tinkering with options. i don't know what i'm missing here.
You can use the apollo-server-plugin-http-headers package for setting cookies in apollo server.
Usage is as simple as this from within your resolvers:
context.setCookies.push({
name: "cookieName",
value: "cookieContent",
options: {
domain: "example.com",
expires: new Date("2021-01-01T00:00:00"),
httpOnly: true,
maxAge: 3600,
path: "/",
sameSite: true,
secure: true
}
});