I'm trying to upload a multipart form with vue3 and dropzone, to my nodejs/express backend and handling it with multer.
My dropzone configuration looks like this:
let files = ref([]);
let dropzoneFile = ref("");
const drop = (e) => {
dropzoneFile.value = e.dataTransfer.files[0];
files.value.push(dropzoneFile.value);
};
const selectedFile = () => {
dropzoneFile.value = document.querySelector(".dropzoneFile").files[0];
files.value.push(dropzoneFile.value);
};
watch(
() => [...files.value],
(currentValue) => {
return currentValue;
}
);
return { dropzoneFile, files, drop, selectedFile, v$: useVuelidate(), getAccessTokenSilently };
And from my template:
<DropZone #drop.prevent="drop" #change="selectedFile" />
<ul class="list-unstyled mb-0" id="dropzone-preview">
<div
class="border rounded"
v-for="(file, index) of files"
:key="index"
>
<div class="d-flex p-2">
<div class="flex-grow-1">
<div class="pt-1">
<h5 class="fs-14 mb-1" data-dz-name="">
{{ file.name }}
</h5>
<p class="fs-13 text-muted mb-0" data-dz-size="">
<strong>{{ file.size / 1024 }}</strong> KB
</p>
<strong
class="error text-danger"
data-dz-errormessage=""
></strong>
</div>
</div>
<div class="flex-shrink-0 ms-3">
<button
data-dz-remove=""
class="btn btn-sm btn-danger"
#click.prevent="deleteRecord"
>
Delete
</button>
</div>
</div>
</div>
</ul>
My posting method:
async add(){
console.log(this.files);
this.name = this.$refs.name.value
this.type = this.$refs.type.value
this.description = this.$refs.description.value
let formData = new FormData();
formData.append('name', this.$refs.name.value);
formData.append('type', this.$refs.type.value);
formData.append('description', this.$refs.description.value);
formData.append('files', this.files);
//const accessToken = await this.getAccessTokenSilently();
//const { data, error } = await post(accessToken,formData);
/* (data) {
console.log(data);
this.myAddModal.hide()
}
if (error) {
console.log(error);
}*/
},
The line console.log(this.files);
Prints out the following to my console:
Proxy {0: File, 1: File}
[[Handler]]
:
Object
[[Target]]
:
Array(2)
0
:
File {name: '10128.tiff', lastModified: 1672418629650, lastModifiedDate: Fri Dec 30 2022 17:43:49 GMT+0100 (Central European Standard Time), webkitRelativePath: '', size: 180224, …}
1
:
File {name: 'body.svg', lastModified: 1672659212900, lastModifiedDate: Mon Jan 02 2023 12:33:32 GMT+0100 (Central European Standard Time), webkitRelativePath: '', size: 825329, …}
length
:
2
[[Prototype]]
:
Array(0)
[[IsRevoked]]
:
false
The receiving code at my node/express backend looks like this:
Router.post("/add", upload.array('files'), validateAccessToken, (req, res) => {
Multer doesn't save the files and I'm having a hard time understanding the format the files are being send to the server?
Is there something wrong with the format the files are being send to the server?
Related
Hello I'm trying to add a new file using Angular and Nodejs into my mongodb database
The backend function works fine on postman
But on the frontend it gives me an error and i didnt figure out what's the problem
It used to work up until I made some changes in the backend function
this is my POST API
router.post('/create',multer({ storage : storage}).any(), (req, res) => {
var sample = fs.readFileSync('./uploads/'+req.files[0].filename,'utf8');
function Filetostring(){
let arr = sample.split(/\r?\n/);
// Find returns the first element that matches our criteria
const step = arr.filter((step , idx)=> {
if (step.includes("step")) {
console.log(step); //this gives me the first result I need
return true;
}
return false;
});
let stepss = JSON.stringify(step)
let newString = stepss.replace(/[\[\]\'\s]/g, ' ');
let newString2 = newString.replace(/"/g, '');
let newString3 = newString2.replace(/#step/g, '');
let newString4 = newString3.replace(/,/g, '\n');
return newString4;
}
let steps = Filetostring()
console.log(steps)
var tc = new Testcase({
name: req.body.name,
upload: req.files[0].filename ,
run : steps,
modify: req.body.modify,
delete: req.body.delete,
step1: req.body.step1,
step2: req.body.step2,
step3: req.body.step3,
step4: req.body.step4,
step5: req.body.step5,
step6: req.body.step6,
step7: req.body.step7,
});
console.log(req.files[0].filename);
tc.save((err, doc) => {
if (err) { res.status(401).send("errorrrrr") }
else {
res.status(200).send(doc)
}
});
});
This is my service.ts
private create = 'http://localhost:5555/testcase/create';
postTestCase(testcase,file:File) {
const formData = new FormData();
formData .append('file', file);
formData .append('name', testcase.name);
formData .append('step1', testcase.step1);
formData .append('modify', testcase.modify);
formData .append('run', testcase.run);
formData .append('delete', testcase.delete);
formData .append('step2', testcase.step2);
formData .append('step3', testcase.step3);
formData .append('step4', testcase.step4);
formData .append('step5', testcase.step5);
formData .append('step6', testcase.step6);
formData .append('step7', testcase.step7);
return this.http.post<any>(this.create, formData );
}
this is my component.ts
addtestcaseData = {'name': '',
'step1': '',
'modify': '',
'run': '',
'delete': '',
'upload': File = null,
'step2': '',
'step3': '',
'step4': '',
'step5': '',
'step6': '',
'step7':''}
addtestcase(){
this.testcaseService.postTestCase(this.addtestcaseData,this.addtestcaseData.upload)
.subscribe(
res => {
console.log(res)
this._router.navigate(['/admin'])
},
err => {
console.log(err);
}
)
};
handleFileInput(files: FileList) {
this.addtestcaseData.upload = files.item(0);
}
And this is my component.html
<div class="card rounded-0">
<div class="card-header">
<h3 class="mb-0">Add Test Case</h3>
</div>
<div class="card-body">
<form class="form" #testcaseForm="ngForm" enctype="multipart/form-data" >
<div class="form-group">
<label for="uname1">Name</label>
<input [(ngModel)]="addtestcaseData.name" class="form-control rounded-0" name="Name" type="text" required>
</div>
<div class="form-group">
<label for="file" class="mr-2">Upload Test Case</label>
<input type="file"
id="file" name="file"
(change)="handleFileInput($event.target.files)">
<!--<button (click)="addfile()" type="button" class="btn btn-success float-right">Add File</button>
-->
</div>
<button (click)="addtestcase()" type="button" class="btn btn-success float-right">Add</button>
</form>
</div>
<!--/card-block-->
</div>
Try to get file with req.file
var tc = new Testcase({
name: req.body.name,
upload: req.file,
run : steps,
modify: req.body.modify,
delete: req.body.delete,
step1: req.body.step1,
step2: req.body.step2,
step3: req.body.step3,
step4: req.body.step4,
step5: req.body.step5,
step6: req.body.step6,
step7: req.body.step7,
});
console.log(req.files[0].filename);
And for route
router.post('/create',multer({ storage : storage}).single('upload'), (req, res) => {
For frontend change the name of input to
<input type="file"
id="file" name="upload"
(change)="handleFileInput($event.target.files)">
I'm new using parse and I'm trying to get the objects from my database and displaying them with ejs using a for loop in my webpage. I'm using back4app as my database.
Here's what I'm doing:
const Car = Parse.Object.extend('Vehicle');
const query = new Parse.Query(Car);
app.get('/', function(req, res){
const VehicleInfo = [
{
VehicleName: query.get('Name'),
Description: query.get('Description'),
Price: query.get('Price'),
Rating: query.get('Rating'),
Route: query.get('Route'),
PassengerAmount: query.get('PassengerAmount')
}
]
try{
res.render('index', {
title: 'mainPage',
VehicleData: VehicleInfo
});
}catch(error){
throw error.message;
}
});
I query this and all 5 of my vehicles are displayed in the console.log but when trying to do the same in my .ejs file this shows up and only one div displays
enter image description here
Here's how I'm using the for loop
<% for (var CarInfo of VehicleData) { %>
<div class="row">
<div class="col-lg-4 col-md-6">
<!-- Car Item-->
<div class="rn-car-item">
<div class="rn-car-item-review">
<div class="fas fa-star"></div> <%= CarInfo.Rating %>
</div>
<div class="rn-car-item-thumb">
<a href="/car-single">
<img class="img-fluid" src="/images/car-1.jpg" alt="Black Sedan" srcset="/images/car-1.jpg 1x, /images/car-1#2x.jpg 2x"/>
</a>
</div>
<div class="rn-car-item-info">
<h3>
<%= CarInfo.VehicleName %>
</h3>
<p>Descripcion: <%= CarInfo.Description %></p>
<div class="rn-car-list-n-price">
<ul>
<li>Ruta: <%= CarInfo.Route %></li>
<li>Cantidad de Pasajeros: <%= CarInfo.PassengerAmount %></li>
</ul>
<div class="rn-car-price-wrap">
<a class="rn-car-price" href="/car-single">
<span class="rn-car-price-from">Desde</span>
<span class="rn-car-price-format">
<span class="rn-car-price-amount">$<%= CarInfo.Price %></span>
<span class="rn-car-price-per">/day</span>
</span>
</a>
</div>
</div>
</div>
</div>
<!-- End Car Item-->
</div>
</div>
<% } %>
I'm sure your code doesn't work like this, also not in the console. You need to run find or first in order to fetch objects.
The other problem is that your Promise hasn't been resolved and doesn't contain the result when you pass it on to the .ejs file. It works in the console because the result in the console will be updated once the Promise is resolved.
You need to do
const VehicleInfo = [];
const query = new Parse.Query(Car);
query.find().then(result => {
result.forEach(vehicle => {
VehicleInfo.push({
VehicleName: result.get('Name'),
Description: result.get('Description'),
Price: result.get('Price'),
Rating: result.get('Rating'),
Route: result.get('Route'),
PassengerAmount: query.get('PassengerAmount')
});
});
}).catch(error => {
console.error('error fetching objects', error);
});
Alternatively you can await the result for cleaner code:
app.get('/', async function(req, res) {
const VehicleInfo = [];
const query = new Parse.Query(Car);
try {
const result = await query.find();
result.forEach(vehicle => {
VehicleInfo.push({
VehicleName: result.get('Name'),
Description: result.get('Description'),
Price: result.get('Price'),
Rating: result.get('Rating'),
Route: result.get('Route'),
PassengerAmount: query.get('PassengerAmount')
});
});
} catch (error) {
console.error('error fetching objects', error);
}
});
Here's more about Promises in JavaScript
I am trying to upload/and save an image in base64 format to my mongo database.
If I use a very very small image it works, but I try to use an image of 161 kb, I have this error:
PayloadTooLargeError: request entity too large
So I try to convert my image with Json but I got an error or it doesn't work,
Her my code ( I am using vue):
<template>
<div class="profile">
<div class="px-4">
<div class="row justify-content-center">
<div class="col-lg-3 order-lg-2">
<div class="card-profile-image image-preview">
<div v-if="profImage !=undefined && profImage.length > 0">
<a>
<img
:src="profImage"
class="rounded-circle"
/>
</a>
</div>
<div>
<div class="file-upload-form">
Upload image:
<input
type="file"
#change="previewImage"
accept="image/*"
/>
</div>
<div class="image-preview" v-if="imageData.length > 0">
<img class="preview" :src="imageData" />
<button #click="updateUserImage"></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Here my js file:
<script>
import DataService from '#/services/DataService'
export default {
name: 'Profile',
data: function() {
return {
username: '',
imageData: '',
profImage: '',
}
},
methods: {
previewImage: function(event) {
var input = event.target
if (input.files && input.files[0]) {
var reader = new FileReader()
reader.onload = e => {
this.imageData = e.target.result
}
reader.readAsDataURL(input.files[0])
}
},
async getAllInfo() {
var userImage = await DataService.getUserImage({
username: this.username
})
this.profImage = userInfo.data.user[0].profImage //IT Works
this.profImage = JSON.parse(userInfo.data.user[0].profImage) //I get an error
},
async updateUserImage() {
var temp = JSON.stringify(this.imageData)
console.log(this.firstname)
await DataService.updateUserInfo({
username: this.username,
user: {
profImage: temp
}
})
}
},
mounted() {}
}
</script>
When I try to use "JSON.parse(userInfo.data.user[0].profImage)"I get an error :
"Unexpected token d in JSON at position 0"
I also try with JSON.Stringify, but I get is not a function.
In my db, the image is saved in this way:
profImage: {
image: Buffer,
require: false
},
What am I doing wrong? I am using mongodb, vue , express and node.
I change the parser limit using
bodyParser.json({ limit: "50mb" })
and works for me
I am trying to get back a record out of my MongoDB database using user input on an Angular template. Here's what's in my api.js file:
// Response handling
let response = {
status: 200,
key: [],
message: null
};
router.get('/keys/:key', (req, res, next) => {
connection((db) => {
db.collection('keys')
.findOne({key: req.params.key})
.then((keys) => {
response.key = keys;
res.json(keys);
})
.catch(err => {
return next({ status: 500, message: 'messed up'})
});
});
});
Here's my keys.service.ts file:
#Injectable()
export class KeysService {
result: any
constructor(private _http: Http) {}
getKeys(typeKey) {
return this._http.get(`/api/keys/:key${typeKey}`)
.map(result => this.result = result.json().key);
}
}
Here's the template (I apologize about the formatting):
<div class="container">
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
</div>
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<input type="text" [(ngModel)]="typeKey">
<button class="btn btn-primary" (click)="getKeyClass(typeKey)">Check Your
Key Spelling</button>
<br><br>
<h2>The Correct Key Spelling is: {{ keySpelling }}</h2>
</div>
</div>
</div>
What I am receiving as an error right now is "type error, can not read property key of null". It is referring to "key" in the keys.service.ts file on the last line.
I am not using mongoose or monk here. I had this working with a general query of my db that gave me the entire contents of the collection "keys" but when I try and make an individual query, no dice. Anyone have any ideas what I am doing wrong?
I have the daturi of an image which is uploaded from the desktop.I would like to send this data uri to express server so as to save the dataUri in a text file. Since the size of the data uri of the image is quite large I am getting payload too large error which is understandable. I tried using multer but I couldn't figure out how to extract the data uri of the image when multer is used, on the server side.Any help on this is greatly appreciated.
Below is some of the code sample that I am trying to use
<div class="row">
<div class="form-group">
<label class="btn btn-default btn-file" for="FileUpload">Upload a Plan</label>
<input type="file" id ="FileUpload" accept="image/*" capture="camera" value="" onchange="readFileURL(this);" style="display: none;">
<img id="chosenFile" src="#" style="visibility: hidden;"/>
</div>
</div>
<div class="row">
<div class="col-sm-12"><button style="background-color: green" class="btn btn-default btn-sm" onclick="handleUplod(this)">Upload</button></div>
</div>
<script type="text/javascript">
function readFileURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
document.getElementById("chosenFile").style.visibility="visible";
reader.onload = function (e) {
$('#chosenFile').attr('src', e.target.result).width(150).height(150);
console.log("result:",e.target.result);
imageData = e.target.result;
};
console.log("data url:"+reader.readAsDataURL(input.files[0]));
}
};
function handleUplod(){
$.ajax({
type: "POST",
url: "/send",
data: { MyPlanDataUri:imageData },
success: function(result){
location.href= "/someplace";
},
error: function(result) {
alert('error');
}
});
};
On the server side I am doing the following
app.post('/send', function(req,res) {
var Tex1 = req.body.MyPlanDataUri;
var newFile = "ImageFile.txt";
fs.writeFile(newFile, Tex1, (err) => {
if (err) res.send(err);
console.log('File saved successfully ! - ', newFile);
}
);
res.send("Successfull");
}
P.S the above code works perfectly fine for small datauri's