Using multer in middleware and passing the file object to the next - node.js

I am using multer function and expect to access the file object in the next middleware. In the first case I succeed and in the second one I fail and I am wondering why
/*The below code works perfectly req.file object is printed successfully */
app.post('/api/v1/tasks/insertproduct', multerUpload.single('productImage'),(req,res,next) => {
console.log(req.file);
});
/*However the following code , I dont have any luck to get the file object printed */
CloudinaryUpload = (req,res,next) => {
console.log('Iam in cloudinary middleware');
console.log('REQ: ' + req.file)
}
app.post('/api/v1/tasks/insertproduct', multerUpload.single('productImage'),CloudinaryUpload);

Related

NodeJS Passing Express res to completely different module

I have an program that susposed to load js to server side dynamically by url (for organizing js files)
app.get('/*',function(req,res){
... path etc. code
if(compare(list,path)){
const js = require('/Js/'+list.find(x => x.pageUrl == path).js)
js.run(req,res)
}
... more code there
}
but for some reason passed res doesnt work and i get res.send is not defined error
here is the other module that i get path from url and load it
exports.run = function run(req,res)
{
res.Send("test") //not defined for some reason
console.log(res) //it is not undefined, i see stuff
res.end()
}
Your code says res.Send instead of res.send.

Node Js API : where the undefined comes from?

I write this code to get the array from url. this is the url : http://localhost:3000/main?a=aaa.jpg&a=bbb.jpg
And here is the code :
//Define module
var express = require('express');
var app = express();
const { exec } = require('child_process');
//extract function
function extract (req,res,next){
res.write(`filename : ${req.query.a}`); //kt page
console.log(req.query.a);//kt terminal
next();
};
//main function
function main (req,res,next){
res.write('\nkuor dok \n');
res.end();
};
app.use(extract);
app.get('/main',main);
app.listen(3000);
This is the output in terminal.
Array(2) ["aaa.jpg", "bbb.jpg"]
undefined
The question is where the undefined comes from? It affected everything i need to do. The array is perfectly fine. But suddenly undefined comes out. Can anyone help me. Thank you in advance.
I tried the code you provided above and i got only the array in the terminal
[ 'aaa.jpg', 'bbb.jpg' ]
When i tried the url in the browser i got
filename : aaa.jpg,bbb.jpg
kuor dok
as the output. i didn't get any undefined
I see that you are trying to define extract function as a middleware. It will be executed for every request
try to comment app.get:
app.use(extract);
//app.get('/main', main);
app.listen(3000);
Then try to make the request
GET: http://localhost:3000/main?a=aaa.jpg&a=bbb.jpg
you will get
[ 'aaa.jpg', 'bbb.jpg' ]
You are handling the request twice. First by the global middleware, the second time by app.get() that calls also the middleware extract before main
As I see app.get don't handle your query params and you got undefined due to an empty object try to log: req.query intead of req.query.q
function extract(req, res, next) {
res.write(`filename : ${req.query.a}`); //kt page
console.log(req.query); //kt terminal
next();
};

fs.createReadStream getting a different path than what's being passed in

I'm using NodeJS on a VM. One part of it serves up pages, and another part is an API. I've run into a problem, where fs.createReadStream attempts to access a different path than what is being passed into the function. I made a small test server to see if it was something else in the server affecting path usage, for whatever reason, but it's happening on my test server as well. First, here's the code:
const fs = require('fs');
const path = require('path');
const csv = require('csv-parser');
const readCSV = (filename) => {
console.log('READ CSV GOT ' + filename); // show me what you got
return new Promise((resolve, reject) => {
const arr = [];
fs.createReadStream(filename)
.pipe(csv())
.on('data', row => {
arr.push(row);
})
.on('error', err => {
console.log(err);
})
.on('end', () => {
resolve(arr);
});
}
}
// tried this:
// const dir = path.relative(
// path.join('path', 'to', 'this', 'file),
// path.join('path', 'to', 'CONTENT.csv')
// );
// tried a literal relative path:
// const dir = '../data/CONTENT.csv';
// tried a literal absolute path:
// const dir = '/repo/directory/server/data/CONTENT.csv';
// tried an absolute path:
const dir = path.join(__dirname, 'data', 'CONTENT.csv');
const content = readCSV(dir)
.then(result => {console.log(result[0]);})
.catch(err => {console.log(err);});
...but any way I slice it, I get the following output:
READCSV GOT /repo/directory/server/data/CONTENT.csv
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, open '/repo/directory/data/CONTENT.csv'
i.e., is fs.createReadStream somehow stripping out the directory of the server, for some reason? I suppose I could hard code the directory into the call to createReadStream, maybe? I just want to know why this is happening.
Some extra: I'm stuck on node v8.11, can't go any higher. On the server itself, I believe I'm using older function(param) {...} instead of arrow functions -- but the behavior is exactly the same.
Please help!!
Code is perfect working.
I think you file CONTENT.csv should be in data folder like "/repo/directory/data/CONTENT.csv".
I'm answering my own question, because I found an answer, I'm not entirely sure why it's working, and at least it's interesting. To the best of my estimation, it's got something to do with the call stack, and where NodeJS identifies as the origin of the function call. I've got my server set up in an MVC pattern so my main app.js is in the root dir, and the function that's being called is in /controllers folder, and I've been trying to do relative paths from that folder -- I'm still not sure why absolute paths didn't work.
The call stack goes:
app.js:
app.use('/somepath', endpointRouter);
...then in endpointRouter.js:
router.get('/request/file', endpointController.getFile);
...then finally in endpointController.js:
const readCSV = filename => {
//the code I shared
}
exports.getFile = (req, res, next) => {
// code that calls readCSV(filename)
}
...and I believe that because Node views the chain as originating from app.js, it then treats all relative paths as relative to app.js, in my root folder. Basically when I switched to the super unintuitive single-dot-relative path: './data/CONTENT.csv', it worked with no issue.

Node.Js promises and async/await

I am trying to use a oai-pmh harvester to harvest all articles from oai repositor and store them in a local mongo database.
I have a small demo.js file to test and print the titles on the console and it works perfectly. This is my demo.js file:
const oaipmh = require('./my_modules/harvester/harvester.js');
const urlProvider='any OAI URL repo'; // change URL here
let harvester=new oaipmh.Harvester(urlProvider);
harvester.harvest(processItem,function(err,res){
console.log(res);
});
Function processItem(item){
try{
let titles=item.metadata['oai:dc:dc']['dc:title'];
let title=(typeof titles=='object')?titles.join("\n"):titles;
console.log(title);
console.dir(item.metadata['oai_dc:dc']);
}catch(err){
// handle errors here
}
};
I am still trying to learn how to use promises and async/await and how to handle it. So far I have tried to use it inside my controller, but I am getting an error.
On my router file i have:
router.route('/doc')
.get(doc.aggregate_one);
On my controller file i have:
var Doc=require('../models/docModel);
const aoipmh=require('../../harvester/harvester');
exports.aggregate_one = async (req,res,next) => {
const urlProvider = req.header('url');
let harvester=new oaipmh.Harvester(urlProvider);
harveste.harvestAsync(urlProvider,processItemmfunction(err,res){
// do something
});
};
I want to send the URL in the header of my get instead of the barcode. When I am trying to test the GET I am receiving an UnhandledPromiseRejectionWarning: Error; Unexpected status code 400 (expected 200)
How can I use the example of the demo.js file inside my controller in order to handle the Promise?

Check uploaded file extension in Sails js

How we can check uploaded file extension in sails js?
I tried on skipper and multer but have no result.
any suggestion?
You should use saveAs options for each file before saving.
var md5 = require('md5');
module.exports = {
testUpload:function(req,res){
// setting allowed file types
var allowedTypes = ['image/jpeg', 'image/png'];
// skipper default upload directory .tmp/uploads/
var allowedDir = "../../assets/images";
// don not define dirname , use default path
req.file("uploadFiles").upload({
saveAs:function(file, cb) {
var d = new Date();
var extension = file.filename.split('.').pop();
// generating unique filename with extension
var uuid=md5(d.getMilliseconds())+"."+ extension;
// seperate allowed and disallowed file types
if(allowedTypes.indexOf(file.headers['content-type']) === -1) {
// save as disallowed files default upload path
cb(null,uuid);
}else{
// save as allowed files
cb(null,allowedDir+"/"+uuid);
}
}
},function whenDone(err,files){
return res.json({
files:files,
err:err
});
});
}
}
Just get uploaded files array and check last chunk of string after dot.
req.file('file').upload({
maxBytes: 2000000,
dirname: 'uploadFolder'
}, function (error, files) {
if (error) return sails.log.error(error);
// You have files array, so you can do this
files[0].fd.split('.').pop(); // You get extension
}
What is going on here? When upload is finished you will get array of files with their filenames. You can get data from that array and see where this file is located (full path).
The last thing is splitting string by dots and get last item from the array with pop() method.

Resources