Related
I am trying to develop Mern Stack mobile application using Reactnative I am getting two error one from frontend
AxiosError: Request failed with status code 500
Backend Error from node PayloadTooLargeError: request entity too large
i have tried different method to post the data right now I am using formdata to append the code and axios to post the code
here is frontend code:
export default class Sellnow extends Component {
constructor(props) {
super(props);
this.onChangePetName = this.onChangePetName.bind(this);
this.onChangePetTitle = this.onChangePetTitle.bind(this);
this.onChangePetContact = this.onChangePetContact.bind(this);
this.onChangePetPrice = this.onChangePetPrice.bind(this);
this.onChangePetDescription = this.onChangePetDescription.bind(this);
this.onValueChangeCat= this.onValueChangeCat.bind(this);
this.onValueChangeCity= this.onValueChangeCity.bind(this);
this.onFileChange = this.onFileChange.bind(this);
// this.pickImage = this.pickImage.bind(this);
this.onSubmit = this.onSubmit.bind(this);
// State
this.state = {
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat:"",
selectedcity:"",
imgforsell:"",
//collection categories
category: [
{
itemName: "Select Category...."
},
{
itemName: "Pets Food"
},
{
itemName: "Pets Products"
},
{
itemName: "Pets Accessories"
}
],
// cities category
cityCategory:[
{
itemName: "Select City...."
},
{
itemName: "Islamabad"
},
{
itemName: "Rawalpindi"
},
{
itemName: "Lahore"
},
{
itemName: "Peshawar"
},
{
itemName: "Karachi"
},
{
itemName: "Quetta"
}
]
};
}
/*componentDidMount() {
axios.get('http://localhost:3000/PetsBazar/pets/' )
.then(res => {
this.setState({
name: res.data.name,
title: res.data.title,
contact: res.data.contact
});
})
.catch((error) => {
console.log(error);
})
}*/
onChangePetName(e) {
this.setState({ name: e.target.value });
}
onChangePetTitle(e) {
this.setState({ title: e.target.value });
}
onChangePetContact(e) {
this.setState({ contact: e.target.value });
}
onChangePetPrice(e) {
this.setState({ price: e.target.value });
}
onChangePetDescription(e) {
this.setState({ description: e.target.value });
}
// categories function
onValueChangeCat(e) {
this.setState({ selectedcat: e.targetvalue })
}
// city function
onValueChangeCity(e) {
this.setState({ selectedcity: e.targetvalue })
}
onFileChange(e) {
this.setState({ imgforsell: e.targetvalue})}
// uploading Image
_getPhotoLibrary = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
base64: true,
exif: true,
aspect: [4, 3]
});
if (!result.cancelled) {
this.setState({ imgforsell: result });
}
this.props.navigation.setParams({
imgforsell: this.state.imgforsell
});
};
async onSubmit() {
// e.preventDefault();
/*const petsObject = {
name: this.state.name,
title: this.state.title,
contact: this.state.contact,
price: this.state.price,
description: this.state.description,
selectedcat:this.state.selectedcat,
selectedcity:this.state.selectedcity,
imgforsell:this.state.imgforsell
};
*/
//const formData = new FormData();
// const FormData = global.FormData;
const formData = new FormData();
formData.append("name", this.state.name);
/*formData.name = this.state.name,
formData.title = this.state.title
formData.contact = this.state.contact
formData.price = this.state.price
formData.description = this.state.description
formData.selectedcat = this.state.selectedcity
formData.imgforsell= this.state.imgforsell*/
//formData.append("name",name);
formData.append("title", this.state.title);
//formData.append("title", title);
formData.append("contact", this.state.contact);
//formData.append("contact", contact);
formData.append("price", this.state.price);
// formData.append("price", price);
formData.append("description", this.state.description);
//formData.append("description", description);
formData.append("selectedcat", this.state.selectedcat);
//formData.append("selectedcat", selectedcat);
formData.append("selectedcity", this.state.selectedcity);
// formData.append("selectedcity", selectedcity);
formData.append("imgforsell",this.state.imgforsell)
/*const newImageUri = "file:///" + imgforsell.split("file:/").join("");
formData.append('imgforsell', {
uri: newImageUri,
//uri:`${fileToUpload.fieldname}-${Date.now()}${path.extname(fileToUpload.originalname)}`,
type: mime.getType(newImageUri),
name: newImageUri.split("/").pop()
}
)*/
// from stack overflow
/*
fetch(
`http://${
Platform.OS === "android" ? ` 192.168.88.45 `: `localhost`
}:4000/pets/addpets`,
// 'http://192.168.88.45:4000/pets/addpets/',
formData,
//'http://10.0.2.2:4040/pets/addpets/',
//formData,
{
method: 'POST',
//body: JSON.stringify(formData),
body:formData,
mode: 'cors',
headers: {
//Accept: 'application/json',
//"content-Type": `multipart/form-data; boundary={formData._boundary}`,
'Content-Type':'multipart/form-data;'
},
//body:QueryString.stringify(formData)
// headers:{"Content-type":"application/json"}
}
)
.then((res) => {
if (!res.ok) {
return Promise.reject(res);
}
return res.json();
})
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
this.setState({
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat: "",
selectedcity: "",
imgforsell: "",
});
});
*/
/* axios
.post(
// `http://${
// Platform.OS === "android" ? "192.168.88.45" : "localhost"
//}:4000/pets/addpets`,
//formData,
`http://192.168.88.45:4000/pets/addpets`, formData
)
.then(({ data }) => {
console.log(data);
})
.catch((err) => {
console.error(err.toJSON());
// res.status(500).json(err) 👈 don't do this, it's not Express
})
.finally(() => {
this.setState({
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat: "",
selectedcity: "",
imgforsell: "",
});
});*/
await axios({
method: "post",
//url: "http://192.168.88.45:4000/pets/addpets",
url:'http://10.0.2.2:4000/pets/addpets',
data: JSON.stringify(formData),
headers: {
// "Content-Type": `multipart/form-data`,
//'content-type': 'application/x-www-form-urlencoded'
"Content-Type" : "application/json"
},
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
this.setState({
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat:"",
selectedcity:"",
imgforsell:""
});
};
//}
render() {
const {imgforsell} = this.state
return (
<View>
<ScrollView
nestedScrollEnabled={true}
showsVerticalScrollIndicator={false}
>
<View style={styles.container}>
<View style={styles.formContainer}>
<Text style={styles.conText}>Please Fill the Below Form </Text>
<View style={styles.borderForm}>
<Text style={styles.formText}>Your Name</Text>
<TextInput
style={styles.formInput}
multiline
placeholder="Please Enter Your Name"
maxLength={15}
value={this.state.name}
onChange={this.onChangePetName}
blurOnSubmit={true}
onChangeText={(name) => this.setState({ name })}
/>
<Text style={styles.formText}>Category</Text>
{ /*<CategoryDropList />*/ }
<View style={styles.viewStyle}>
<Picker
itemStyle={styles.itemStyle}
mode="dropdown"
style={styles.pickerStyle}
selectedValue={this.state.selectedcat}
// onValueChange={this.onValueChangeCat.bind(this)}
//onValueChange={(selectedcat)=>this.setState({selectedcat})}
onValueChange={(itemValue,itemIndex)=> this.setState({selectedcat:itemValue})}
>
{this.state.category.map((item, index) => (
<Picker.Item
color="black"
label={item.itemName}
value={item.itemName}
index={index}
/>
))}
</Picker>
</View>
<Text style={styles.formText}>Pet/Product Title</Text>
<TextInput
style={styles.formInput}
placeholder="Enter Product Title"
maxLength={15}
value={this.state.title}
blurOnSubmit={true}
onChange={this.onChangePetTitle}
onChangeText={(title) => this.setState({ title })}
/>
<Text style={styles.formText}>City</Text>
{/*<CityDropList />*/}
<View style={styles.viewStyle}>
<Picker
itemStyle={styles.itemStyle}
mode="dropdown"
style={styles.pickerStyle}
selectedValue={this.state.selectedcity}
onValueChange={(itemValue,itemIndex)=> this.setState({selectedcity:itemValue})}
>
{this.state.cityCategory.map((item, index) => (
<Picker.Item
color="black"
label={item.itemName}
value={item.itemName}
index={index}
/>
))}
</Picker>
</View>
<Text style={styles.formText}> Contact Number </Text>
<TextInput
style={styles.formInput}
placeholder="Phone Number"
inputType="number"
maxLength={11}
keyboardType="number-pad"
blurOnSubmit={true}
value={this.state.contact}
onChange={this.onChangePetContact}
onChangeText={(contact) => this.setState({ contact })}
/>
<Text style={styles.formText}>Price</Text>
<TextInput
style={styles.formInput}
multiline
placeholder="Enter Price"
inputType="number"
keyboardType="number-pad"
blurOnSubmit={true}
maxLength={7}
value={this.state.price}
onChange={this.onChangePetPrice}
onChangeText={(price) => this.setState({ price })}
/>
<Text style={styles.formText}>Image of Product</Text>
{/*<ImagePickerExample />*/}
<TouchableOpacity id="fileinput" style={styles.btn} onPress={this._getPhotoLibrary.bind(this)}>
<Text style={styles.btnTxt}> Choose File</Text>
</TouchableOpacity>
{imgforsell ? (
<Image source={{ uri: imgforsell.uri }} style={styles.uploadimgstyle} />
) : (
<View/>
)}
<Text style={styles.formText}>
Description(Optional max 150 words)
</Text>
<TextInput
style={styles.descriptionInput}
multiline
placeholder="Describe your product"
maxLength={150}
blurOnSubmit={true}
value={this.state.description}
onChange={this.onChangePetDescription}
onChangeText={(description) => this.setState({ description })}
/>
<TouchableOpacity style={styles.btn} onPress={this.onSubmit}>
<Text style={styles.btnTxt}>Submit</Text>
</TouchableOpacity>
</View>
</View>
</View>
</ScrollView>
</View>
);
}
}
Routes.js
// Importing important packages
const express = require("express");
const sharp = require('sharp');
bodyParser = require("body-parser");
//const RNFS = require('react-native-fs');
// Using express and routes
const app = express();
const petRoute = express.Router();
//Import multer
const multer = require("multer");
//file system
const fs = require("fs");
//path
path = require("path");
//moongoose
const mongoose = require('mongoose');
const petModel = require("../Models/PetsSell");
// pet module which is required and imported
//petModel = require("../Models/PetsSell");
//const { db } = require("../Models/PetsSell");
// To Get List Of pets
petRoute.route("/").get(function (req, res) {
petModel.find(function (err, pet) {
if (err) {
console.log(err);
} else {
res.json(pet);
}
});
});
// Multer
//geeksforgeeks code {/*https://www.geeksforgeeks.org/upload-and-retrieve-image-on-mongodb-using-mongoose/#:~:text=So%20for%20storing%20an%20image,in%20the%20form%20of%20arrays.*/}
/*
petRoute.route('/addpets').post( upload.single('imgforsell'), (req, res, next) => {
var obj = {
name: req.body.name,
title: req.body.title,
contact: req.body.contact,
price: req.body.price,
description: req.body.description,
selectedcat: req.body.selectedcat,
selectedcity: req.body.selectedcity,
imgforsell: {
data: fs.readFileSync(path.join(__dirname + './Upload/Images/' + req.file.filename)),
contentType: 'image/jpg'
}
}
petModel.save(obj, (err, item) => {
if (err) {
console.log(err);
}
else {
// item.save();
res.redirect('/addpets');
}
});
});
*/
// Updating Multer
/*
const storage = multer.diskStorage({
destination: "./Upload/Images",
filename: (req, file, cb) => {
return cb(
null,
//file.originalname
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
//`${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`
);
},
});
const upload = multer({
storage: storage,
limits: {
fileSize: 900000,
},
});*/
/*var dir = "../Upload/Images";
var upload = multer({
storage: multer.diskStorage({
destination: function (req, file, callback) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
callback(null, "../Upload/Images");
},
filename: function (req, file, callback) {
callback(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
}),
fileFilter: function (req, file, callback) {
var ext = path.extname(file.originalname);
if (ext !== ".png" && ext !== ".jpg" && ext !== ".jpeg") {
return callback(//res.end('Only images are allowed')
null, false);
}
callback(null, true);
},
});*/
{/* From here Changing code to string type data base */ }
/*app.post( '/pets/addpets',upload.single('imgforsell'), (req, res) => {
try {
if (
req.file &&
req.body &&
req.body.name &&
req.body.description &&
req.body.price &&
req.body.title &&
req.body.selectedcity &&
req.body.contact &&
req.body.selectedcat
) {
let new_product = new petModel();
new_product.name = req.body.name;
new_product.description = req.body.description;
new_product.price = req.body.price;
new_product.imgforsell = req.file.originalname;
new_product.title = req.body.title;
new_product.selectedcat = req.body.selectedcat;
new_product.contact = req.body.contact;
new_product.selectedcity = req.body.selectedcity;
//new_product.user_id = req.user.id;
new_product.save((err, data) => {
if (err) {
res.status(400).json({
errorMessage: err,
status: false,
});
} else {
res.status(200).json({
status: true,
title: "Product Added successfully.",
});
}
});
} else {
res.status(400).json({
errorMessage: "Add proper parameter first!",
status: false,
});
}
} catch (e) {
res.status(400).json({
errorMessage: "Something went wrong!",
status: false,
});
}
});*/
{/* Previous Code to add Pets */}
const storage = multer.diskStorage({
destination: "./Upload/Images",
filename: (req, file, cb) => {
return cb(
null,
//file.originalname
// path='../Upload/Images/',
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
//`${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`
);
},
});
const upload = multer({
storage: storage,
limits: {
fileSize: 900000,
},
});
petRoute.route("/addpets").post(upload.single("imgforsell"), (req, res) => {
console.log(req.file);
var img = fs.readFileSync(req.file.path);
//var img = fs.readFileSync(req.body.path);
var encode_image = img.toString("base64");
const pet = new petModel({
name: req.body.name,
title: req.body.title,
contact: req.body.contact,
price: req.body.price,
description: req.body.description,
selectedcat: req.body.selectedcat,
selectedcity: req.body.selectedcity,
imgforsell: Buffer.from(encode_image, "base64"),
//imgforsell:req.body.imgforsell,
contentType: req.file.mimetype,
//contentType: multipart/form-data
});
pet
.save()// img
.then((img) => {
//img.id
res.json(img.id);
})
.catch((err) => {
//remove return and curly braces
return res.json(err)});
});
/*petRoute.route("/pets/addpets").post(upload.single("imgforsell"), (req, res) => {
console.log(req.file);
var img = fs.readFileSync(req.file.path);
//var img = `${RNFS.DocumentDirectoryPath}//${new Date().toISOString()}.jpg`.replace(/:/g, '-');
{/*var img = `${fs.DocumentDirectoryPath}//${new Date().toString()}.jpg`.replace(`/g`, '-')
if(Platform.OS === 'ios') {
// console.log(path, dest);
fs.copyAssetsFileIOS(response.origURL, img, 0, 0)
.then(res => {})
.catch(err => {
console.log('ERROR: image file write failed!!!');
console.log(err.message, err.code);
});
} else if(Platform.OS === 'android') {
//console.log(path, dest);
fs.copyFile(response.uri, img)
.then(res => {})
.catch(err => {
console.log('ERROR: image file write failed!!!');
console.log(err.message, err.code);
});
}
// here was comment star and slash please add
//var img = fs.readFileSync(req.body.path);
var encode_image = img.toString("base64");
const pet = new petModel({
name: req.body.name,
title: req.body.title,
contact: req.body.contact,
price: req.body.price,
description: req.body.description,
selectedcat: req.body.selectedcat,
selectedcity: req.body.selectedcity,
imgforsell: Buffer.from(encode_image, "base64"),
//imgforsell:req.body.imgforsell,
contentType: req.file.mimetype,
});
pet
.save(img)// img
.then((img) => {
//img.id
res.json(img.id);
})
.catch((err) => {
//remove return and curly braces
return res.json(err)});
});*/
petRoute.route("/pets/addpets").get((req, res) => {
var filename = req.params.id;
petModel.findOne(
{ _id: mongoose.Types.ObjectId(filename) },
(err, result) => {
if (err) return console.log(err);
console.log(result);
res.contentType(result.contentType);
res.send(new Buffer.from(result.imgforsell.buffer, "base64"));
}
);
}
);
// To Add New pet
/*petRoute.route('/addpets').post(function (req, res) {
let pet = new petModel(req.body);
pet.save()
.then(game => {
res.status(200).json({ 'pets': ' Added Pets' });
})
.catch(err => {
res.status(400).send("Something Went Wrong");
});
});*/
// To Get pet Details By pet ID
/*petRoute.route('/editPets/:id').get(function (req, res) {
let id = req.params.id;
petModel.findById(id, function (err, pet) {
res.json(pet);
});
});*/
// To Update The pet Details
/*
petRoute.route('/updatePets/:id').post(function (req, res) {
petModel.findById(req.params.id, function (err, pet) {
if (!pet)
return next(new Error('Unable To Find Pets With This Id'));
else {
pet.name = req.body.name;
pet.title = req.body.title;
pet.contact = req.body.contact;
pet.save().then(emp => {
res.json('Pets Updated Successfully');
})
.catch(err => {
res.status(400).send("Unable To Update Pets");
});
}
});
});*/
// To Delete The pet
/*
petRoute.route('/deletePets/:id').get(function (req, res) {
petModel.findByIdAndRemove({ _id: req.params.id }, function (err, pet) {
if (err) res.json(err);
else res.json('pet Deleted Successfully');
});
});*/
module.exports = petRoute;
server.js
// Imported required packages
const express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
cors = require('cors'),
mongoose = require('mongoose');
var cors_proxy = require('cors-anywhere');
// MongoDB Databse url
var mongoDatabase = 'mongodb://localhost:27017/PetsBazar';
// Created express server
const app = express();
mongoose.Promise = global.Promise;
// Connect Mongodb Database
mongoose.connect(mongoDatabase, { useNewUrlParser: true }).then(
() => { console.log('Database is connected') },
err => { console.log('There is problem while connecting database ' + err) }
);
// All the express routes
const petRoutes = require('./Routes/PetsSell.Routes');
// Conver incoming data to JSON format
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({ // to support URL-encoded bodies
extended: false,
})
);
// Enabled CORS
app.use(cors());
app.use(express.static("./Upload/Images"));
// Setup for the server port number
const port = process.env.PORT || 4000;
// Routes Configuration
app.use('/pets', petRoutes);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "192.168.88.45:4000"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// Staring our express server
const server = app.listen(port, function () {
console.log('Server Lisening On Port : ' + port);
});
/*cors_proxy.createServer({
originWhitelist: [], // Allow all origins
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: ['cookie', 'cookie2']
}).listen(port, '192.168.88.45', function() {
console.log('Running CORS Anywhere on ' + ':' + port);
});
*/
you can add this line in your backend
app.use(express.bodyParser({limit: '50mb'}));
I have a challenge with express-fileupload when a user doesn't upload a file that is meant to be optional.
Someone should please help me out.
This is my code:
const file = req.files.document;
const file2 = req.files.document2;
const uploader = req.body.fullname;
const filename = `CV_${uploader}_${file.name}`;
const filename2 = `Cover_${uploader}_${file2.name}`;
let savedFile = filename.replace(/\s+/g, "");
let savedFile2 = filename2.replace(/\s+/g, "");
const path = "uploads/" + savedFile;
const path2 = "uploads/" + savedFile2;
file.mv(path, (err) => {
if (err) {
console.log(err);
}
});
file2.mv(path2, (err) => {
if (err) {
console.log(err);
}
});
The second file is optional for the user to upload. When the user doesn't upload it, it shows an error.
Please, how can I make it optional from here.
It shows an error like this:
Type Error: Cannot read property 'name' of undefined
Thank you so much.
So, I was able to find my way around the whole thing.
I did it like this...
app.post("/form", (req, res) => {
const file = req.files.document;
const file2 = req.files.document2;
const uploader = req.body.fullname;
const filename = `CV_${uploader}_${file.name}`;
let savedFile = filename.replace(/\s+/g, "");
const path = "uploads/" + savedFile;
file.mv(path, (err) => {
if (err) {
console.log(err);
}
});
// function to save file2 to server if it exists and send the filename to be used outside the function
const filename2 = file2 ? `Cover_${uploader}_${file2.name}` : null;
let savedFile2 = filename2 ? filename2.replace(/\s+/g, "") : null;
const path2 = filename2 ? "uploads/" + savedFile2 : null;
if (file2 && file2.name) {
const filename2 = `Cover_${uploader}_${file2.name}`;
let savedFile2 = filename2.replace(/\s+/g, "");
const path2 = "uploads/" + savedFile2;
file2.mv(path2, (err) => {
if (err) {
console.log(err);
}
});
}
// Saving to the database...
const date = new Date();
const dateNow = moment(date).format("llll");
const job = new Jobs({
position: req.body.positions,
language: req.body.lang,
fullName: req.body.fullname,
gender: req.body.gender,
education: req.body.education,
email: req.body.email,
address: req.body.address,
phone: req.body.phone,
fileCV: savedFile,
fileCover: savedFile2,
date: dateNow,
});
job.save((err) => {
if (!err) {
res.render("success");
}
});
// Sending to mail server
const output = `
<p> You have a new applicant! </p>
<h2> Contact Details </h2>
<ul>
<li>position: ${req.body.positions}</li>
<li>language: ${req.body.lang} </li>
<li>fullName: ${req.body.fullname}</li>
<li>gender: ${req.body.gender}</li>
<li>email: ${req.body.email}</li>
<li>address: ${req.body.address}</li>
<li>phone: ${req.body.phone}</li>
<li>education: ${req.body.education}</li>
</ul>
`;
const transporter = nodemailer.createTransport({
service: "localhost",
port: 1025,
secure: false, // true for 465, false for other ports
auth: {
user: "project.1", // generated ethereal user
pass: "secret.1", // generated ethereal password
},
tls: {
rejectUnauthorized: false,
},
});
let senderName = req.body.fullname;
let senderEmail = req.body.email;
//send mail with unicode symbols
let mailOptions = {
from: `"${senderName}" <${senderEmail}>`, // sender address
to: "mikejuwon737#gmail.com, sjobopisa#gmail.com", // list of receivers
subject: "Job Application ✔", // Subject line
text: "Check out my details here...", // plain text body
html: output, // html body
attachments: [
{ filename: `${savedFile}`, path: `${path}` },
{ filename: `${savedFile2}`, path: `${path2}` },
], // list of attachments
};
// sending mail with defined transport object
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log(err);
} else {
console.log("Message sent: %s", info.messageId);
// console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
}
});
});
I want to upload an image to S3 and save to user record with NodeJS, just like the Rails Paperclip gem.
I believe this should be the process, but again I'm quite confused about how this package should work:
receive an image and resize by paperclip
save or update to S3
save file to user in DB
I have a Rails Postgres database, and users can upload an image, stored in S3, and reformatted with Paperclip gem. Here's how it is stored:
irb(main):003:0> user.avatar
=> #<Paperclip::Attachment:0x000055b3e043aa50 #name=:avatar,
#name_string="avatar", #instance=#<User id: 1, email:
"example#gmail.com", created_at: "2016-06-11 22:52:36",
updated_at: "2019-06-16 17:17:16", first_name: "Clarissa",
last_name: "Jones", avatar_file_name: "two_people_talking.gif",
avatar_content_type: "image/gif", avatar_file_size: 373197,
avatar_updated_at: "2019-06-16 17:17:12", #options={:convert_options=>{},
:default_style=>:original, :default_url=>":style/missing.png",
:escape_url=>true, :restricted_characters=>/[&$+,\/:;=?#<>\[\]\
{\}\|\\\^~%# ]/, :filename_cleaner=>nil,
:hash_data=>":class/:attachment/:id/:style/:updated_at",
:hash_digest=>"SHA1", :interpolator=>Paperclip::Interpolations,
:only_process=>[],
:path=>"/:class/:attachment/:id_partition/:style/:filename",
:preserve_files=>false, :processors=>[:thumbnail],
:source_file_options=>{:all=>"-auto-orient"}, :storage=>:s3,
:styles=>{:large=>"500x500#", :medium=>"200x200#",
:thumb=>"100x100#"}, :url=>":s3_path_url",
:url_generator=>Paperclip::UrlGenerator,
:use_default_time_zone=>true, :use_timestamp=>true, :whiny=>true,
:validate_media_type=>true, :adapter_options=>
{:hash_digest=>Digest::MD5},
:check_validity_before_processing=>true, :s3_host_name=>"s3-us-
west-2.amazonaws.com", :s3_protocol=>"https", :s3_credentials=>
{:bucket=>"example", :access_key_id=>"REDACTED",
:secret_access_key=>"REDACTED",
:s3_region=>"us-west-2"}}, #post_processing=true,
#queued_for_delete=[], #queued_for_write={}, #errors={},
#dirty=false, #interpolator=Paperclip::Interpolations,
#url_generator=#<Paperclip::UrlGenerator:0x000055b3e043a8e8
#attachment=#<Paperclip::Attachment:0x000055b3e043aa50 ...>>,
#source_file_options={:all=>"-auto-orient"}, #whiny=true,
#s3_options={}, #s3_permissions={:default=>:"public-read"},
#s3_protocol="https", #s3_metadata={}, #s3_headers={},
#s3_storage_class={:default=>nil},
#s3_server_side_encryption=false, #http_proxy=nil,
#use_accelerate_endpoint=nil>
user.avatar(:thumb) returns:
https://s3-us-west-2.amazonaws.com/example/users/avatars/000/000/001/thumb/two_people_talking.gif?1560705432
Now, I'm trying to allow the user to upload a new/change image through a react-native app, and the backend is Nodejs, which is relatively new to me.
I'm so confused about how to implement this, especially because the examples are all referencing Mongoose, which I'm not using.
Just to show how I'd successfully update the user, here is how to update first_name of the user:
users.updateUserPhoto = (req, res) => {
let id = req.decoded.id
let first_name = req.body.first_name
models.Users.update(
first_name: first_name,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
}
Here is the package I found node-paperclip-s3, and here's what I'm trying to do:
'use strict'
let users = {};
const { Users } = require('../models');
let models = require("../models/index");
let Sequelize = require('sequelize');
let Paperclip = require('node-paperclip');
let Op = Sequelize.Op;
let sequelizeDB = require('../modules/Sequelize');
users.updateUserPhoto = (req, res) => {
let id = req.decoded.id
let avatar = req.body.avatar <- this is a file path
models.Users.plugin(Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: '/users/{{attachment}}/{{id}}/{{filename}}',
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
}
})
models.Users.update(
avatar,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
}
I've also tried something like this:
models.Users.update(Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: '/users/{{attachment}}/{{id}}/{{filename}}',
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
},
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
})
I've tried:
let new_avatar = (Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: `/users/avatars/{{attachment}}/{{id}}/{{filename}}`,
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
},
})
let data = {
avatar: new_avatar
}
models.Users.update(
data,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
From the example in the link above, I don't understand how it is saving to S3, or how it's updating the database in the same way the Rails gem is creating that record.
Question : how to save resized images + original in the exact same way that the Rails paperclip gem is saving to S3 AND the user record in the database.
I originally had this open for a 400 point bounty, and am more than happy to still offer 400 points to anyone who can help me solve this. Thanks!!
The below code is for nodeJs.
I have added an api to save an image from frontend to AWS S3.
I have added comments within code for better understanding.
var express = require("express");
var router = express.Router();
var aws = require('aws-sdk');
aws.config.update({
secretAccessKey: config.AwsS3SecretAccessKey,
accessKeyId: config.AwsS3AccessKeyId,
region: config.AwsS3Region
});
router
.route("/uploadImage")
.post(function (req, res) {
//req.files.imageFile contains the file from client, modify it as per you requirement
var file = getDesiredFileFromPaperclip(req.files.imageFile);
const fileName = new Date().getTime() + file.name;
//before uploading, we need to create an instance of client file
file.mv(fileName, (movErr, movedFile) => {
if (movErr) {
console.log(movErr);
res.send(400);
return;
}
//read file data
fs.readFile(fileName, (err, data) => {
if (err) {
console.error(err)
res.send(400);
}
else {
//as we have byte data of file, delete the file instance
try {
fs.unlink(fileName);
} catch (error) {
console.error(error);
}
//now, configure aws
var s3 = new aws.S3();
const params = {
Bucket: config.AwsS3BucketName, // pass your bucket name
Key: fileName, // file will be saved as bucket_name/file.ext
Body: data
}
//upload file
s3.upload(params, function (s3Err, awsFileData) {
if (s3Err) {
console.error(s3Err)
res.send(400);
} else {
console.log(`File uploaded successfully at ${awsFileData.Location}`)
//update uploaded file data in database using 'models.Users.update'
//send response to client/frontend
var obj = {};
obj.status = { "code": "200", "message": "Yipee!! Its Done" };
obj.result = { url: awsFileData.Location };
res.status(200).send(obj);
}
});
}
});
});
});
This is old school, non - fancy solution.Please try it out and let me know.
I'd need help to understand how to handle multer (nodeJS) with Angular 7.
I tried a bunch of different situation but can't seem to upload any file...
My files come from a ReactiveForm:
<mat-tab
label="Documents"
formGroupName="docs">
<mat-list>
<mat-nav-list>
<a mat-list-item
(click)="fsPicker.click()">
Upload financial statements
</a><input type="file" #fsPicker (change)="onDocPicked($event, 'fs')">
<a mat-list-item
(click)="cdPicker.click()">
Upload the constitutional documents
</a><input type="file" #cdPicker (change)="onDocPicked($event, 'cd')">
<a mat-list-item
(click)="idPicker.click()">
Upload the ID
</a><input type="file" #idPicker (change)="onDocPicked($event, 'id')">
<a mat-list-item
(click)="adPicker.click()">
Upload the bank account details
</a><input type="file" #adPicker (change)="onDocPicked($event, 'ad')">
</mat-nav-list>
</mat-list>
</mat-tab>
Which is controlled by a MimeValidator:
// INSIDE NGONINIT:
this.customerForm = new FormGroup({
info: new FormGroup({
name: new FormControl(null, {validators: Validators.required}),
vat: new FormControl(null, {validators: Validators.required}),
}),
docs: new FormGroup({
fs: new FormControl(null, {asyncValidators: mimeType}),
cd: new FormControl(null, {asyncValidators: mimeType}),
id: new FormControl(null, {asyncValidators: mimeType}),
ad: new FormControl(null, {asyncValidators: mimeType})
})
});
// IN THE REST OF THE CLASS
onDocPicked(event: Event, type: string) {
const file = (event.target as HTMLInputElement).files[0];
this.customerForm.get('docs').patchValue({
[type]: file
});
this.customerForm.get('docs').get(type).updateValueAndValidity();
this.customerForm.get('docs').get(type).markAsDirty();
setTimeout(() => {
if (!this.customerForm.get('docs').get(type).valid) {
this.openAlert();
this.customerForm.get('docs').patchValue({
[type]: null
});
}
}, 100);
}
Then submited and sent to a dedicated service:
onSubmit() {
if (!this.customerForm.valid) {
return;
}
this.isLoading = true;
if (!this.editMode) {
this.customerService.addCustomer(this.customerForm.get('info').value, this.customerForm.get('docs').value);
this.customerForm.reset();
} else {
const updatedCustomer: Customer = {
id: this.id,
name: this.customerForm.get('info').value.name,
vat: this.customerForm.get('info').value.vat
};
this.customerService.updateCustomer(this.id, updatedCustomer);
}
this.router.navigate(['/customers']);
}
Inside the service, handled and sent to the backend:
addCustomer(info, docsData) {
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('docs', docsData);
console.log(docsData);
this.http.post<{message: string, customerId: string}>(
'http://localhost:3000/api/customers',
customerData
)
.subscribe((res) => {
const customer: Customer = {
id: res.customerId,
name: info.name,
vat: info.vat
};
this.customers.push(customer);
this.customersUpdated.next([...this.customers]);
});
}
And last but not least received and handled by the express and multer:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let err = new Error('invalid mime type!');
if (isValid) {
err = null;
}
cb(err, 'backend/docs');
},
filename: (req, file, cb) => {
const name = file.originalname.toLowerCase().split('').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, name + '-' + Date.now() + '.' + ext);
}
});
const upload = multer({storage: storage});
router.post('', upload.any(),
// .fields([
// {name: 'fs'},
// {name: 'cd'},
// {name: 'id'},
// {name: 'ad'},
// ]),
(req, res, next) => {
const customer = new Customer({
name: req.body.name,
vat: req.body.vat,
});
customer.save().then(result => {
res.status(201).json({
message: 'Customer added successfully!',
customerId: result.id
});
});
});
I believe that the problems comes from the object I'm trying to send to the server... But I'm not sure how to handle this properly.
Even by calling multer's any command, nothing get saved.
Here's a link to the full project on stackblitz:
https://stackblitz.com/github/ardzii/test
I was sending the wrong type of data. To correct (and it seems to work now) I had to precise in the FormData that I was appending Files:
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('fs', docsData.fs as File, info.vat + 'fs');
customerData.append('cd', docsData.cd as File, info.vat + 'cd');
customerData.append('id', docsData.id as File, info.vat + 'id');
customerData.append('ad', docsData.ad as File, info.vat + 'ad');
Once done, I could easily handle the files with multer by calling:
upload.
fields([
{name: 'fs', maxCount: 1},
{name: 'cd', maxCount: 1},
{name: 'id', maxCount: 1},
{name: 'ad', maxCount: 1},
]),
upload variable being a multer's instance with parameters (see in the question).
I am using exceljs module for creating excel file. The problem is it is neither getting created nor getting saved in the path.
var excel = require('exceljs');
var options = {
filename: './streamed-workbook.xlsx',
useStyles: true,
useSharedStrings: true
};
var workbook = new Excel.stream.xlsx.WorkbookWriter(options);
var sheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 }
];
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
worksheet.commit();
workbook.commit().then(function(){
console.log('xls file is written.');
});
But when I run the code nothing happens. The excel is not created. What am I missing here?
*********************** Edit **************************
Made the following changes to my code but still its not working.
var Excel = require('exceljs');
var workbook = new Excel.Workbook();
var worksheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 }
];
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
workbook.commit();
workbook.xlsx.writeFile('./temp.xlsx').then(function() {
// done
console.log('file is written');
});
In order to send the excel workbook to the client you can:
Using async await:
async function sendWorkbook(workbook, response) {
var fileName = 'FileName.xlsx';
response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
await workbook.xlsx.write(response);
response.end();
}
Using promise:
function sendWorkbook(workbook, response) {
var fileName = 'FileName.xlsx';
response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
workbook.xlsx.write(response).then(function(){
response.end();
});
}
So I figured out that I was getting an error because of the workbook.commit(). I removed the commit and everything started working like a charm. Here is the entire working code of creating and downloading an excel file:
Note: I am using an npm module called tempfile to create a temporary file path for the created excel file. This file path is then automatically removed. Hope this helps.
try {
var workbook = new Excel.Workbook();
var worksheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 }
];
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
var tempFilePath = tempfile('.xlsx');
workbook.xlsx.writeFile(tempFilePath).then(function() {
console.log('file is written');
res.sendFile(tempFilePath, function(err){
console.log('---------- error downloading file: ' + err);
});
});
} catch(err) {
console.log('OOOOOOO this is the error: ' + err);
}
get answer from this link https://github.com/exceljs/exceljs/issues/37
router.get('/createExcel', function (req, res, next) {
var workbook = new Excel.Workbook();
workbook.creator = 'Me';
workbook.lastModifiedBy = 'Her';
workbook.created = new Date(1985, 8, 30);
workbook.modified = new Date();
workbook.lastPrinted = new Date(2016, 9, 27);
workbook.properties.date1904 = true;
workbook.views = [
{
x: 0, y: 0, width: 10000, height: 20000,
firstSheet: 0, activeTab: 1, visibility: 'visible'
}
];
var worksheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'dob', width: 10, outlineLevel: 1, type: 'date', formulae: [new Date(2016, 0, 1)] }
];
worksheet.addRow({ id: 1, name: 'John Doe', dob: new Date(1970, 1, 1) });
worksheet.addRow({ id: 2, name: 'Jane Doe', dob: new Date(1965, 1, 7) });
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader("Content-Disposition", "attachment; filename=" + "Report.xlsx");
workbook.xlsx.write(res)
.then(function (data) {
res.end();
console.log('File write done........');
});
}
This code snippet is using node.js with the excel4node and express modules in order to convert JSON data to an Excel file and send it to the client, using Javascript.
const xl = require('excel4node');
const express = require('express');
const app = express();
var json = [{"Vehicle":"BMW","Date":"30, Jul 2013 09:24 AM","Location":"Hauz Khas, Enclave, New Delhi, Delhi, India","Speed":42},{"Vehicle":"Honda CBR","Date":"30, Jul 2013 12:00 AM","Location":"Military Road, West Bengal 734013, India","Speed":0},{"Vehicle":"Supra","Date":"30, Jul 2013 07:53 AM","Location":"Sec-45, St. Angel's School, Gurgaon, Haryana, India","Speed":58},{"Vehicle":"Land Cruiser","Date":"30, Jul 2013 09:35 AM","Location":"DLF Phase I, Marble Market, Gurgaon, Haryana, India","Speed":83},{"Vehicle":"Suzuki Swift","Date":"30, Jul 2013 12:02 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Civic","Date":"30, Jul 2013 12:00 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Accord","Date":"30, Jul 2013 11:05 AM","Location":"DLF Phase IV, Super Mart 1, Gurgaon, Haryana, India","Speed":71}]
const createSheet = () => {
return new Promise(resolve => {
// setup workbook and sheet
var wb = new xl.Workbook();
var ws = wb.addWorksheet('Sheet');
// Add a title row
ws.cell(1, 1)
.string('Vehicle')
ws.cell(1, 2)
.string('Date')
ws.cell(1, 3)
.string('Location')
ws.cell(1, 4)
.string('Speed')
// add data from json
for (let i = 0; i < json.length; i++) {
let row = i + 2
ws.cell(row, 1)
.string(json[i].Vehicle)
ws.cell(row, 2)
.date(json[i].Date)
ws.cell(row, 3)
.string(json[i].Location)
ws.cell(row, 4)
.number(json[i].Speed)
}
resolve( wb )
})
}
app.get('/excel', function (req, res) {
createSheet().then( file => {
file.write('ExcelFile.xlsx', res);
})
});
app.listen(3040, function () {
console.log('Excel app listening on port 3040');
});
There is a mistake in your Code.
You have declared your My Sheet with one variable and using a different variable in your entire code.
var sheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 } ];
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
worksheet.commit();
Change variable Sheet to Worksheet. Like the below code
var worksheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 } ];
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
worksheet.commit();
This should fix your issue.
Thanks
var excel = require("exceljs");
var workbook1 = new excel.Workbook();
workbook1.creator = 'Me';
workbook1.lastModifiedBy = 'Me';
workbook1.created = new Date();
workbook1.modified = new Date();
var sheet1 = workbook1.addWorksheet('Sheet1');
var reHeader=['FirstName','LastName','Other Name'];
var reColumns=[
{header:'FirstName',key:'firstname'},
{header:'LastName',key:'lastname'},
{header:'Other Name',key:'othername'}
];
sheet1.columns = reColumns;
workbook1.xlsx.writeFile("./uploads/error.xlsx").then(function() {
console.log("xlsx file is written.");
});
This creates xlsx file in uploads folder.