I have a query, that is how I can send "userURL" variable from below file(imageController.js) to another file(contactController.js). and one thing I want to send only "userURL" variable not the whole function "resize". I tried a lot to solve this issue by using "module.exports" but the problem I got is that "module.exports" sending the whole function "resize" not the "userURL" variable. now in second file "contactController.js" where i have mentioned {userURL} in console.log but it's printing only "your result undefined". I just want to export userURL from first file imageController.js to second file "contactController.js".
imageController.js
exports.resize = async (req, res, next) => {
if(!req.file){
next()
return
}
const extension = req.file.mimetype.split('/')[1]
req.body.userFile = `${uuid.v4()}.${extension}`
const photo = await jimp.read(req.file.buffer)
await photo.resize(500, jimp.AUTO)
await photo.write(`./public/uploads/${req.body.userFile}`)
const userimg = photo;
console.log(`./public/uploads/${req.body.userFile}`)
cloudinary.config({
cloud_name: 'katal',
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
});
cloudinary.v2.uploader.upload(`./public/uploads/${req.body.userFile}`,{
transformation: { width:100, height:100}}, function(error, result) {
console.log('please show result\t' +JSON.stringify(result))
const userURL ='vikivivki'
res.send(result.secure_url)
console.log(result.secure_url)
})
}
contactController.js
const mongoose = require('mongoose')
const Contact = mongoose.model('Contact')
const moment = require('moment-timezone')
const {userURL} = require('./imageController')
exports.contactForm = (req, res) => {
res.render('contact')
}
exports.usermessage = async(req, res) => {
req.body.name = req.body.name
req.body.email = req.body.email
req.body.message = req.body.message
const ind = moment.tz(Date.now(), "Asia/Calcutta")
const newContact = new Contact(req.body)
await newContact.save()
console.log('your result',userURL)
let showResult1 = JSON.stringify(newContact)
let showResult = JSON.parse(showResult1)
res.send(showResult.message)
}
You need to export items you need access to
exports.userURL ='vikivivki'; //exporting here along with rezise as well
file imageController.js
//imageController.js
exports.userURL ='vikivivki'; //exporting here along with rezise as well
exports.resize = async (req, res, next) => {
if(!req.file){
next()
return
}
const extension = req.file.mimetype.split('/')[1]
req.body.userFile = `${uuid.v4()}.${extension}`
const photo = await jimp.read(req.file.buffer)
await photo.resize(500, jimp.AUTO)
await photo.write(`./public/uploads/${req.body.userFile}`)
const userimg = photo;
console.log(`./public/uploads/${req.body.userFile}`)
cloudinary.config({
cloud_name: 'katal',
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
});
cloudinary.v2.uploader.upload(`./public/uploads/${req.body.userFile}`,{
transformation: { width:100, height:100}}, function(error, result) {
console.log('please show result\t' +JSON.stringify(result))
const userURL ='vikivivki'
res.send(result.secure_url)
console.log(result.secure_url)
})
}
In your contactController.js
//contactController.js
const mongoose = require('mongoose')
const Contact = mongoose.model('Contact')
const moment = require('moment-timezone')
const {userURL} = require('./imageController'); // Please have a check on location if they are in the same directory
exports.contactForm = (req, res) => {
res.render('contact')
}
exports.usermessage = async(req, res) => {
req.body.name = req.body.name
req.body.email = req.body.email
req.body.message = req.body.message
const ind = moment.tz(Date.now(), "Asia/Calcutta")
const newContact = new Contact(req.body)
await newContact.save()
console.log('your result',userURL)
let showResult1 = JSON.stringify(newContact)
let showResult = JSON.parse(showResult1)
res.send(showResult.message)
}
Related
i have a table:
CREATE TABLE IF NOT EXISTS bands (
id serial PRIMARY KEY,
name VARCHAR UNIQUE NOT NULL,
creationDate DATE not NULL,
years DATE not NULL
);
I only want to pass name and creation date. what i want is that years will return currentdate - creationDate. The problem is that I do not really know where i should correctly change my code, because im using Node project.
My code looks like this:
const express = require("express");
const app = express();
const pool = require("./db");
app.use(express.json());
// Routes
app.post("/bands", async (req, res) => {
try {
const { name, creationDate } = req.body;
const newBand = await pool.query(
"INSERT INTO bands (name, creationDate,years) VALUES ($1, $2) RETURNING *",
[name, creationDate]
);
res.json(newBand);
} catch (err) {
console.error(err.message);
}
});
app.get("/bands", async (req, res) => {
try {
const allBands = await pool.query("SELECT * FROM bands");
res.json(allBands);
console.log(allBands);
} catch (err) {
console.error(err.message);
}
});
app.get("/bands/:bandsName", async (req, res) => {
console.log(req.params);
const { bandsName } = req.params;
try {
const todo = await pool.query("SELECT * FROM bands WHERE name = $1", [
bandsName,
]);
res.json(todo.rows[0]);
} catch (err) {
console.error(err.message);
}
});
app.put("/bands/:id", async (req, res) => {
try {
const { id } = req.params;
const { name, creationDate } = req.body;
const updateTodo = await pool.query(
"UPDATE band SET name = $1, creationDate = $2 WHERE id = $3",
[name, creationDate, id]
);
res.json("Udało się, zaaktualizowane");
} catch (err) {
console.error(err.message);
}
});
app.delete("/bands/:id", async (req, res) => {
try {
const { id } = req.params;
const deleteTodo = await pool.query("DELETE FROM bands WHERE id = $1", [
id,
]);
res.json("Usunięto");
} catch (err) {
console.error(err.message);
}
});
app.listen(3000, () => {
console.log("server is listening on port 3000");
});
Can anyone tell me where should i change my code so "years" will automatically calculate without me having to put the data in postman?
const { name, creationDate } = req.body;
const d = new Date(creationDate );
const year = d.getFullYear();
Create a date object and retrieve the year would do it
I have a project in Node JS in which I have a form to add new users.
How can I view this information in JSON format?
These are the data that I see:
name age country city
------------------------------
user1 22 Spain Madrid button{View JSON}
When I press the 'View JSON' button, the following must be displayed below the table:
[
"id": 1,
"name": "user1",
"age": 22,
"country": "Spain" {
"city":"Madrid"
}
]
My problem: how can I create a function that performs this conversion? How do I call the function from index.ejs?
I cleared and merged the codes. And I created a new endpoint as /export to export the data as CSV file. I couldn't test it so let me know if it doesn't work.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const MongoClient = require('mongodb').MongoClient;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static('public'));
app.set('views', './src/views');
app.get('/', async (req, res) => {
const db = await mongoDB();
const person = await db.collection('person').find().toArray();
res.render('index.ejs', { person: person })
})
app.get('/export', async (req, res) => {
await convertCSV();
res.status(200).send( { success: 1 });
})
app.post('/person', async (req, res) => {
res.redirect('/');
})
app.listen(process.env.PORT, function () {
console.log(`server: http://${process.env.HOST}:${process.env.PORT}`);
})
const mongoDB = () => {
return new Promise((resolve, reject) => {
const url = 'mongodb://127.0.0.1:27017';
MongoClient.connect(url, { useUnifiedTopology: true })
.then(client => {
const db = client.db('users')
resolve(db);
})
.catch(error => reject(error))
});
}
const convertCSV = () => {
return new Promise((resolve, reject) => {
const converter = require("json-2-csv");
const fetch = require("node-fetch");
const fs = require("fs");
const flatten = require('flat');
const maxRecords = 10;
const getJson = async () => {
const response = await fetch(`http://${process.env.HOST}:${process.env.PORT}/users.json`);
const responseJson = await response.json();
return responseJson;
};
const convertToCSV = async () => {
const json = await getJson();
let keys = Object.keys(flatten(json[0]));
let options = {
keys: keys
};
converter.json2csv(json, json2csvCallback, options);
};
let json2csvCallback = function (err, csv) {
if (err) throw err;
const headers = csv.split('\n').slice(0, 1);
const records = csv.split('\n').slice(0,);
for (let i = 1; i < records.length; i = i + maxRecords) {
let dataOut = headers.concat(records.slice(i, i + 3)).join('\n');
let id = Math.floor(i / maxRecords) + 1;
fs.writeFileSync('data' + id + '.csv', dataOut)
}
};
await convertToCSV();
resolve();
})
}
However, it is not a good practice at all to using controller, index and route in the same file. A better approach would be to create routes, controllers folders and put the codes in a more orderly form.
Something like this (You can find better ones of course mine is just advice):
- index.js
- router.js (A router to manage your endpoints)
- controllers (Controller when you call the endpoint)
-> export.controller.js
-> person.controller.js
- routes (Endpoints)
-> export.route.js
-> person.route.js
- helpers
-> databaseHandler.js (Database connection handler)
I'm using multer for uploading images for creating courses in my application and my courses have images and I have a form for getting the data from user.
I use multer in middleware and add it to my route with upload.single('images') and my field which I get the image from user is named images and that means I have got the image from the user.
When I just click on the save button, I won't get any errors and my server will work like it is stuck in a middleware and when I go to my upload folder, I don't see any images loaded!
And if I load the image I will save the course in my database which is mongo. But I don't find the course saved too.
I have checked the enctype="multipart/form-data" and it was in my form.
And this is my multer middleware code
const multer = require("multer");
const mkdirp = require("mkdirp");
const fs = require("fs");
const getDirImage = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/images/${year}/${month}/${day}`;
};
const ImageStorage = multer.diskStorage({
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
});
},
filename: (req, file, cb) => {
let filePath = getDirImage() + "/" + file.originalname;
if (!fs.existsSync(filePath)) cb(null, file.originalname);
else cb(null, Date.now() + "-" + file.originalname);
},
});
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
});
module.exports = uploadImage;
and this is the middlewares which I referenced it to my handler of route controller
router.post("/courses/create", upload.single("images"), convertFileToField.handle, courseValidator.handle(), courseController.storeCourse);
and this is the convertFileToField Code
const middleware = require('./middleware');
class ConvertFiletoField extends middleware {
handle(req, res, next) {
if (!req.file)
req.body.images = undefined;
else
req.body.images = req.file.filename;
next();
}
}
module.exports = new ConvertFiletoField();
And this is the courseValidator Middleware Code
const validator = require('./validator');
const Course = require("app/models/Course");
const path = require("path");
const { check } = require("express-validator/check");
class courseValidator extends validator {
handle() {
return [
check("title")
.not()
.isEmpty()
.withMessage("فیلد عنوان نمیتواند خالی بماند")
.custom(async (value) => {
const course = await Course.findOne({ slug: this.slug(value)});
if (course) {
throw new Error('we have this course on our site !!!!')
}
}),
check('images')
.custom(async value => {
if (! value) {
throw new Error('You need to enter a course !');
}
let fileExt = ['.png', '.jpg', 'jpeg', '.svg'];
if (! fileExt.includes(path.extname(value)))
throw new Error('the course extention is not valid !');
}),
];
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseValidator();
And Finally this is the post route handler
const controller = require("app/http/controllers/controller");
const Course = require("app/models/Course");
const fs = require('fs');
const path = require("path");
const sharp = require("sharp");
class courseController extends controller {
showCourses(req, res) {
const courses = Course.find({}).sort({ createdAt: -1 });
res.render("admin/courses/index", { courses: courses });
}
createCourse(req, res) {
res.render("admin/courses/create");
}
async storeCourse(req, res) {
let status = await this.validationData(req);
if (!status) {
// For Deleting the saved image because of having validation error
if (req.file)
fs.unlink(req.file.path, (err) => {
console.log(err);
});
return this.back(req, res);
}
// Create the Course
let images = this.imageResize(req.file);
const { title, type, body, price, tags } = req.body;
const newCourse = new Course({
user: req.user._id,
title,
type,
slug: this.slug(),
body,
images: JSON.stringify(images),
price,
tags,
});
await newCourse.save();
return res.redirect("/admin/courses");
}
imageResize(image) {
let imageInfo = path.parse(image.path);
let addressImage = {};
addressImage["original"] = `${imageInfo}/${image.filename}`;
const resize = (size) => {
let imageName = `${imageInfo.name}-${size}${imageInfo.ext}`;
addressImage[size] = this.getUrlImage(`${image.destination}/${imageName}`);
sharp(image.path)
.resize(size, null)
.toFile(`${image.destination}/${imageName}`)
};
[1080, 720, 480].map(resize);
}
getUrlImage(dir) {
return dir.substr(8);
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseController();
I had done everything I could and I had tried all the solutions for loading the image but I get error at my courseValidation middleware.
Please say any solution that is related to multer. I will try it out.
in the destination section of the diskStorage you must be return name of the directory in the callback function. your middleware stoped in this section because you don't call cb function.
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
cb(made)
});
}
here middleware function need to be defined
router.post("/courses/create", multerMiddleWare,..{...});
const multerMiddleWare = (req, res, next) => {
uploadImage(req, res,
(error) => {
if (!error) return next();
return next('error');
});
};
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
}).single("images");
I'm aware this question has been asked before. I tried all the solutions that were provided but still I'm stuck. Please have a look at my code:
1) ReviewController.js
exports.setTourUserIds = (req, res, next) => {
// allow nested route
if (!req.body.tour) req.body.tour = req.params.tourId
if (!req.body.user) req.body.user = req.user.id
next()
}
exports.createReview = handlerFactory.createOne(Review)
exports.updateReview = handlerFactory.updateOne(Review)
exports.deleteReview = handlerFactory.deleteOne(Review)
2) ReviewRoute.js
let express = require('express')
let Router = express.Router({ mergeParams: true })
let reviewController = require('../controllers/reviewController')
let authController = require('../controllers/authController')
Router
.route('/')
.get(reviewController.getAllReviews)
.post(authController.protect,
authController.restrictTo('user'),
reviewController.setTourUserIds,
reviewController.createReview)
Router
.route('/:id')
.get(authController.protect, reviewController.getReview)
.patch(reviewController.updateReview)
.delete(reviewController.deleteReview)
module.exports = Router
3) handlerFactory.js
exports.createOne = Model => catchAsync(async (req, res, next) => {
let doc = await Model.createOne(req.body)
if (!doc) {
return next(new AppError('No document found with that ID', 404))
}
res.status(201).json({
status: 'success!',
data: { doc }
})
})
Please change your code from
exports.createReview = handlerFactory.createOne(Review)
exports.updateReview = handlerFactory.updateOne(Review)
exports.deleteReview = handlerFactory.deleteOne(Review)
to
exports.createReview = () => { handlerFactory.createOne(Review)}
exports.updateReview = () => { handlerFactory.updateOne(Review) }
exports.deleteReview = () => { handlerFactory.deleteOne(Review) }
You should pass a function to the router
Check following syntax:
Router
.route('/:id').post(function(){})
Is it possible to use Probot to create an issue on response from an express route? I've tried the following, but they async function can't access context.github.
const createIssue = async function (issue, context) {
const owner = issue.owner; const repo = issue.repo; const title = issue.title; const body = issue.body; const assignees = issue.assignees; const labels = issue.labels
return context.github.issues.create({ owner, repo, title, body, labels, assignees })
}
const router = app.route('/robot')
router.use(require('express').static('public'))
router.get('/test', (req, res) => {
const issue = {
repo: 'reponame',
owner: 'ownername',
title: req.query.title,
labels: req.query.lab,
body: req.query.body,
assignees: req.query.as
}
createIssue(issue, context).then(
res.send('Success')
).catch(err => console.log(err))
})
I think this might be what you are looking for: https://probot.github.io/api/latest/classes/application.html#auth
const createIssue = async function (issue, app) {
const github = await app.auth();
const owner = issue.owner; const repo = issue.repo; const title = issue.title; const body = issue.body; const assignees = issue.assignees; const labels = issue.labels
return github.issues.create({ owner, repo, title, body, labels, assignees })
}
const router = app.route('/robot')
router.use(require('express').static('public'))
router.get('/test', (req, res) => {
const issue = {
repo: 'reponame',
owner: 'ownername',
title: req.query.title,
labels: req.query.lab,
body: req.query.body,
assignees: req.query.as
}
const
createIssue(issue, app).then(
res.send('Success')
).catch(err => console.log(err))
})