Upload multiple Files in angular node multer - node.js

I am facing problem while uploading multiple files in angular, node, multer.
Last file in array is uploaded to server.
Here is my HTML.
<div class="mb-1">
<p class="text-muted m-0">Anti Black List</p>
<input type="file" (change)="fileChangeEvent($event)" name="Anti Black List" id="4" #fileDataAntiBlackList (onFileSelected)="onFileSelected($event ,fileDataAntiBlackList)" ng2FileSelect [uploader]="uploader" accept="application/pdf"/>
</div>
<div class="mb-1">
<p class="text-muted m-0">Anti Black List</p>
<input type="file" (change)="fileChangeEvent($event)" name="Shop Act" id="3" #fileDataShopAct (onFileSelected)="onFileSelected($event ,fileDataShopAct)" ng2FileSelect [uploader]="uploader" accept="application/pdf"/>
</div>
<div class="mb-1">
<p class="text-muted m-0">Anti Black List</p>
<input type="file" (change)="fileChangeEvent($event)" name="Professional Tax" id="2" #fileDataPRO (onFileSelected)="onFileSelected($event ,fileDataPRO)" ng2FileSelect [uploader]="uploader" accept="application/pdf"/>
</div>
<div class="mb-1">
<p class="text-muted m-0">Anti Black List</p>
<input type="file" (change)="fileChangeEvent($event)" name="GST Copy" id="1" #fileDataGST (onFileSelected)="onFileSelected($event ,fileDataGST)" ng2FileSelect [uploader]="uploader" accept="application/pdf"/>
</div>
<mat-label>First name</mat-label>
<input formControlName="f_name" matInput type="text" name="first_name" placeholder="First name" required/>
<mat-label>Last name</mat-label>
<input formControlName="l_name" matInput type="text" name="Last_name" placeholder="Last name" required/>
<button mat-raised-button color="primary" class="mx-4" (click)="onSubmit()"
[disabled]="uploader.getNotUploadedItems().length && signupForm.invalid">Upload And Save </button>
There are more fields, but i have shown less here.
Following is TS file code
filesToUpload: Array<File> = [];
fileChangeEvent(fileInput: any) {
this.filesToUpload = <Array<File>>fileInput.target.files;
//this.product.photo = fileInput.target.files[0]['name'];
}
onSubmit() {
//let files = this.getFiles();
let dbId: number;
let formData = new FormData();
const files: Array<File> = this.filesToUpload;
for(let i = 0; i < files.length;i++){
formData.append("files", files[i], files[i]['name']);
}
formData.append('first_name',this.signupForm.value.f_name);
this.http.post('http://localhost:3000/api/newUpload', formData)
.map(files => files)
.subscribe(files => console.log('files', files));
return false;
}
This is my backend API
Upload
let user_storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR);
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now() + '' + path.extname(file.originalname));
}
});
let upload = multer({ storage: user_storage }).array('files',10);
API function
router.post('/newUpload',function(req,res){
console.log('before upload',req.body);
upload(req,res,function(err) {
//console.log(req.body);
//console.log(req.files);
if(err) {
return res.end("Error uploading file.");
}
console.log('files', req.files);
console.log(req.body);
res.send(req.files);
//res.end("File is uploaded");
});
});
This is what i have tried. Only last file in array is save in uploads folder.
Also i want to insert first name , last name etc to database but when i console req.body is gives empty json {}
Edit quetion
i got where i am missing.
Its in angular code : when i print
const files: Array<File> = this.filesToUpload;
i get last file which i uploaded. means it takes last file which is uploaded not all files.
so i use following function
getFiles(){
return this.uploader.queue.map((fileItem) => {
return fileItem.file;
});
}
So in onsubmit function
onSubmit() {
let files = this.getFiles();
let formData = new FormData();
for(let i = 0; i < files.length;i++){
console.log(files[i]);
formData.append("files", files[i],files[i]['name']);
}
When i console files[i], get all files.
But in line formData.append line i get following error
Argument of type 'FileLikeObject' is not assignable to parameter of type 'string | Blob'.
Property 'slice' is missing in type 'FileLikeObject' but required in type 'Blob
P.S : when i send file name in formdata.append, i get all file names in node serevr.

After trying different solutions, finally i got working solutions by which multiple files and other input fields are also send to sever.
In my Edit part of question, i have use following function
getFiles(){
return this.uploader.queue.map((fileItem) => {
return fileItem.file;
});
}
above code was giving error. I have just changed return line.
from
return fileItem.file;
to
return fileItem.file.rawFile;
Thats it. All remaining code is same as in edit.

you forget to add multer middleware to your router.post
it should be
outer.post('/newUpload',
upload.array('myFiles', 12),
function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.send(req.files);
//res.end("File is uploaded");
});
});

Related

how to delete object array from node js

I am creating a simple todolist using react js and node js without database (to store data in objact array) I need to delete elements one by one by clicking. For each element I have Delete button. now todo list delete from front end(react), how to delete it from node any one please help me
todo.js
function Remove(id) {
const updateTodos=[...tasks].filter((obj)=>obj.id!==id)
setTasks(updateTodos)
}
if(isLogged){
return (
<div >
<h1>ToDo List</h1>
<form onSubmit={HandleSubmit}>
<input type="text" placeholder=" Add item..." name="list" value={toDos} onChange={(e)=>setToDos(e.target.value)}/>
<button id="btn" type="submit">Add</button>
</form>
<ul>
{tasks.map(obj=><li key={obj.id}>{obj.toDo}<button type='delete' onClick={(e)=>Remove(obj.id)} >Delete</button>
<input type="checkbox" id="" name=""onChange={(e)=>{
console.log(e.target.checked)
console.log(obj)
setTasks(tasks.filter(obj2=>{
if(obj2.id===obj.id){
obj2.status=e.target.checked
}
return obj2
}))
}} value={obj.status} /> </li>)}
</ul>
<h4>Completed tasks</h4>
{tasks.map((obj)=>{
if(obj.status){
return(<h5>{obj.toDos}</h5>)
}
return null
})}
</div>
);
}
}
export default Todo;
node- index.js
const lists =[
{id: new Date(),toDo:"learn react"}
]
app.post('/Todo',function(req, res){
lists.push({"id":new Date(),"toDo":req.body.list,"status":false})
console.log(lists)
res.status(200).json(lists[lists.length-1])
})
app.get('/Todo', (request, response) => response.status(200).json(lists));
req.body.list.pop()
res.status(200).json({"id":new Date(),"toDo":req.body.list,"status":false})
This will remove the last element in the list

Post image file using axios in react app sending strange data to backend

I'm currently trying to post a photo file upload to my backend, to be stored in the file system. However, whenever I do, it produces an absolutely bizarre string of numbers / letters when I console log the req.body.
I've no idea what this is, why it's happening or how to convert it into the image I need to store in my file system.
Here's my uploadPhoto and buttonClick (aka submit) functions:
const uploadPhoto = (e) => {
e.preventDefault()
setPreviewPhoto(URL.createObjectURL(e.target.files[0]))
setPhotoFile(e.target.files[0])
}
const buttonClick = async (e) => {
e.preventDefault()
const formData = new FormData()
formData.append('photoFile', photoFile)
await axios.post("/api/uploadProfilePicture", formData, { headers: { 'content-type': 'multipart/form-data' }}, { transformRequest: formData => formData })
}
And here's my form that's used to upload the image:
<form className="setup-form" method="POST" encType="multipart/form-data" onSubmit={buttonClick}>
<label className="setup-label">Your name</label>
<input className="setup-input" type="text" name="name" onChange={onChange} value={name} />
<label className="setup-label">Your photo</label>
<div className="setup-photo-hint-container">
<div className="setup-photo-div">
<label for="photoFile" className="setup-photo-label">Upload</label>
<input className="setup-photo-input" id="photoFile" type="file" onChange={uploadPhoto} name="photoFile" />
</div>
</div>
</form>
Does anyone have any idea what I'm doing wrong here? I don't understand why it's going to the request body for one, or why it's producing these characters for another.

How to upload an image in mongoose-node app using ckeditor. File will be uploaded to s3

I'm using CKEditor to upload content in mongoose.
I want images to be uploaded along with the content.
I'm storing the images to s3 and mongodb stores the image path in string (when not uploading with ckeditor).
I'm trying to use this module
https://github.com/mjadobson/ckeditor5-sss-upload
I'm trying this code
build-config.js
module.exports = {
// ...
plugins: [
"#ckeditor/ckeditor5-essentials/src/essentials",
// ...
//'#ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter',
//'#ckeditor/ckeditor5-easy-image/src/easyimage',
"ckeditor5-sss-upload/src/s3upload"
// ...
],
// ...
config: {
toolbar: {
items: [
"headings",
"bold",
"italic",
"imageUpload",
"link",
"bulletedList",
"numberedList",
"blockQuote",
"undo",
"redo"
]
}
// ...
}
};
seminar.js
const build_config=require('../build-config');
router.get('/add',ensureAuthenticated,(req,res)=>{
SeminarGamenameConf.find().then(gameName_list=>{
SeminarGametypeConf.find().then(gameType_list=>{
console.log(gameType_list);
res.render('cms/seminar/add',{
gameName_list_array:gameName_list,
gameType_list_array:gameType_list,
country: countries,
build_config:build_config
});
})
})
});
//add.handlebars
<script src="/ckeditor5-build-classic/ckeditor.js"></script>
<form action="/cms/seminar/add" enctype="multipart/form-data" method="post" >
<div class="form-group">
<label for="seminar_detail">Seminar Details</label>
<textarea class="form-control" id="editor1" name="seminar_detail</textarea>
<input type="submit" value="submit"/>
</div>
</form>
<script>
ClassicEditor.create(document.querySelector("#editor"), {
s3Upload: {
policyUrl: "http://127.0.0.1/my-upload-endpoint",
mapUrl: ({ location, bucket, key }) => {
return location;
}
}
});
</script>
I'm really confused. I don't know how to upload images to s3 using ckeditor (in between the details).
Please help.
If there is any other method, please reply

I can't upload file in adonis js, move is not function

I have the following file type field
<form action = "javascript:;" enctype="multipart/form-data" id="formulario" class="form-horizontal">
<div class="form-group">
<div class="span7">
<input type="file" multiple class="file file-loading" data-preview-file-type="any" id="fileUp" name="fileUp[]">
</div>
</div>
</form>
and in the controller i have this for upload file
const Helpers = use('Helpers')
const myFile = request.file('fileUp')
const directory = Helpers.publicPath()
await myFile.move(directory, {
overwrite: true
})
but return error "move is not function"
i don't understand
Your input is for multiple files (fileUp[]), the docs has a section for multiple file upload,you should use moveAll() instead of move()
await profilePics.moveAll(Helpers.tmpPath('uploads'))
if (!profilePics.movedAll()) {
return profilePics.errors()
}

how to read xml file content from file in react?

I'm sure this question has been asked before but i can't find it in Stakoverflow
i'm doing a simple site where you upload an xml and it parses it to json.
i'm having a form to upload the xml:
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input
type="file"
ref={input => {
this.App = input;
}}
/>
</label>
<br />
<button type="submit">Submit</button>
</form>
and my lisenter:
handleSubmit(event) {
//here the file will be opened
//submit pressed
event.preventDefault();
alert(
`Selected file - ${this.App.files[0].name}`
);
}
how do i extract the xml content from the file in the event ?
i want to have a String with the xml content from the file
thnx !!!
Found it i used this code:
var rawFile = new XMLHttpRequest();
var allText;
rawFile.open("GET", this.App.files[0], false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
allText = rawFile.responseText;
// alert(allText);
}
}
}
rawFile.send(null);

Resources