Upload image with Multer and Formik to Mongodb (MERN) - node.js

I created app using MERN.
Now I'm trying to upload image with Multer and Formik, but req.file returns undefined, and I can't understand why.
I'm new in this, but I guess this may cause from JSON.stringify (http.hook) or content-type: application/json. I also tried do this with FormData, but that's not working. Any ideas?
UPDATE: With Postman works good. I think problem is in ui part, input doesn,t pass the file.
app.js
const {Router} = require('express');
const multer = require('multer');
const auth = require('../middleware/auth.middleware');
const Users= require('../models/Users');
const router = Router();
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './client/public/uploads/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
},
});
const upload = multer({
storage: storage,
limits: { fileSize: 10 * 1024 * 1024 }
});
router.post('/create', upload.single('image'), auth, async (req, res) => {
console.log(req.file);
try {
const code = req.body.code;
const existing = await Users.findOne({code: code});
if(existing) {
return res.json({user: existing})
}
const user = new Users(req.body);
await user .save();
res.status(201).json(user);
} catch (e) {
console.log(e);
res.status(500).json({ message: 'Error: try again.' })
}
});
http.hook.js
import {useState, useCallback} from 'react';
export const useHttp = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const request = useCallback(async (url, method = 'GET', body = null, headers = {}) => {
setLoading(true);
try {
if(body) {
body = JSON.stringify(body);
headers['Content-Type'] = 'application/json';
}
const response = await fetch(url, {method, body, headers});
const data = await response.json();
if(!response.ok) {
throw new Error(data.message || 'Something goes wrong')
}
setTimeout(() => {
setLoading(false);
}, 800);
return data
} catch (e) {
setLoading(false);
setError(e.message);
throw e;
}
}, []);
const clearError = useCallback(() => {setError(null)}, []);
return {loading, request, error, clearError}};
CreateUser.js
import React, {useCallback, useContext, useEffect, useState} from 'react';
import {useHttp} from "../hooks/http.hook";
import Button from "../components/Button/Button";
import {AuthContext} from "../context/auth.context";
import {Formik} from "formik";
export const CreateUser = () => {
const {token} = useContext(AuthContext);
const {loading, request} = useHttp();
const createUser = useCallback(async (body) => {
try {
const fetched = await request(`/api/user/create`, 'POST', body, {
Authorization: `Bearer ${token}`
});
} catch (e) {console.log(e)}
}, []);
const handleCreate = (values, {resetForm}) => {
console.log(values);
createUser(values);
// resetForm({});
};
return (
<div className="wrapper">
<div className="row">
<div className="column small-12 text-center color-white mb_45">
<div className="custom-headline text text-48 font-bold">
<h1>
Crate user
</h1>
</div>
</div>
</div>
<Formik
enableReinitialize
initialValues={{
name: '',
code: '',,
image: null
}}
onSubmit={handleCreate}
>
{({
values,
errors,
touched,
handleBlur,
handleChange,
handleSubmit,
isSubmitting,
setFieldValue,
resetForm
}) => (
<form onSubmit={handleSubmit} className="row align-center">
<div className="column small-12 large-7">
<div className="form-item flex-container align-middle mb_20">
<label className="text text-14 font-semibold font-uppercase text-right small-4">
Photos
</label>
<input id="image" type="file" name="image" className="file_input"
onChange={(event) => {
setFieldValue("image", event.currentTarget.files[0]);
}} />
</div>
</div>
<div className="column small-12 large-7">
<div className="form-item flex-container align-middle mb_20">
<label className="text text-14 font-semibold font-uppercase text-right small-4">
Name
</label>
<input
className="text text-17 "
type="text"
name="name"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
/>
</div>
</div>
<div className="column small-12 large-7">
<div className="form-item flex-container align-middle mb_20">
<label className="text text-14 font-semibold font-uppercase text-right small-4">
Code
</label>
<input
className="text text-17"
type="text"
name="code"
onChange={handleChange}
onBlur={handleBlur}
value={values.code}
/>
</div>
</div>
<div className="column small-12 mt_20">
<div className="btn_group flex-container flex-wrap align-middle align-center">
<Button className="btn-lg radius-8" theme="blue"
text={Submit} type="submit"
/>
</div>
</div>
</form>
)}
</Formik>
</div>
)
};

Wrap out your image file with formData with the multer key "image"
upload.single('image')
on Front-End
const handleCreate = async (values) => {
try {
const body = new FormData();
body.append( "image", values.image);
...
} catch (err) {}
};
And make sure about your destination path use "dirname"
`${__dirname}/../client/public/uploads/`
Change this according to your directory path

OK! I don't know WHY this was cause, but I found solution - I use axios instead of fetch, and of course FormData for uploading images or files, and it works!
Hope this may be helpful for someone else. Thanks for all answers.
const handleCreate = (values, {resetForm}) => {
const formData = new FormData();
formData.append('name', values.name);
formData.append('code', values.code);
formData.append('image', values.image);
axios.post('/api/user/create', formData)
.then(console.log)
catch(console.error);
resetForm({});
};

I have 2-3 suggestion,
in your app.js file
router.post('/create', upload.single('image'), auth, async (req, res) => {
console.log(req.file);
you should use auth middelware before using upload.single.
and you should send headers with POST request with {content type: multipart/form-data}

Related

how to solve this Cannot POST error in MERN?

I am inserting two images along with the form data into MongoDB database.
While both images are stored in my pc folder but all form data isn't uploading in the database.
error
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /</pre>
</body>
</html>
in my console. Please help me how to solve that.
I have tried some previously asked question in stackOF.
app.js
const express = require("express")
const app = express()
const cors = require('cors');
const env = require("dotenv")
const port = 5000
env.config({path: "../server/config.env"})
require("../server/db/conn")
app.use(cors());
app.use(express.json())
app.use(require("../server/router/auth"))
app.listen(port, (err) => {
if (err) {
return console.error(err);
}
return console.log(`server is listening on ${port}`);
});
module.exports = "conn"
register.js(frontend)
const Register = () => {
const [newUser, setNewUser] = useState({
school: "",
address: "",
photo: "",
photoone: ""
});
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("school", newUser.school);
formData.append("photo", newUser.photo);
formData.append("photoone", newUser.photoone)
formData.append("address", newUser.address);
axios({
method: "post",
url: "/teacher",
data: formData,
headers: { "Content-Type": "multipart/form-data" },
})
.then((response) => {
console.log(response)
}).then((data) => {
console.log(data)
}).catch((error) => {
if (error.response) {
console.log(error.response.data)
}
})
};
const handleChange = (e) => {
setNewUser({ ...newUser, [e.target.name]: e.target.value });
};
const handlePhoto = (e) => {
setNewUser({ ...newUser, photo: e.target.files[0] });
};
const handlePhotoone = (e) => {
setNewUser({ ...newUser, photoone: e.target.files[0] });
};
return (
<>
<div className="container main">
<div className="row">
<div className="col-sm-6 col-md-6 col-lg-6">
<form onSubmit={handleSubmit} encType="multipart/form-data">
<div class="mb-3">
<label class="form-label">
Your school
</label>
<input
type="text"
class="form-control"
id="exampleInputPassword1"
id="school"
name="school"
value={newUser.school}
onChange={handleChange}
/>
</div>
<div class="input-group mb-3">
<input
type="file"
id="pic"
accept=".png, .jpg, .jpeg"
name="photo"
onChange={handlePhoto} type="file" class="form-control" id="inputGroupFile02" />
</div>
<div class="input-group mb-3">
<input
type="file"
id="pic"
placeholder="second photo"
accept=".png, .jpg, .jpeg"
name="photoone"
onChange={handlePhotoone} type="file" class="form-control" id="inputGroupFile01" />
</div>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">
your address
</label>
<input
type="text"
id="address"
name="address"
value={newUser.address}
onChange={handleChange}
class="form-control"
aria-describedby="emailHelp"
/>
</div>
<button
value="register"
type="submit"
class="btn btn-primary"
>
Submit
</button>
</form>
</div>
</div>
</div>
</>
);
};
auth.js(backend)
const mongoose = require("mongoose")
const express = require("express")
const router = express()
require("../db/conn")
const User = require("../model/userSchema")
const Teacher = require("../model/userSchemaTeacher")
const multer = require('multer');
let path = require('path');
let fs = require("fs-extra");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
let schoolname = req.body.school;
let path = `C:/Users/kumar/Desktop/mern/server/images/${schoolname}`;
fs.mkdirsSync(path);
cb(null, path);
// cb(null, 'images');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const fileFilter = (req, file, cb) => {
const allowedFileTypes = ['image/jpeg', 'image/jpg', 'image/png'];
if (allowedFileTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(null, false);
}
}
let upload = multer({ storage, fileFilter });
router.route('/teacher').post(upload.fields([{
name: "photo", maxCount: 1
}, {
name: "photoone", maxCount: 1
}
])), (req, res) => {
const school = req.body.school;
const photo = req.file.filename
const photoone = req.file.filename
const address = req.body.address;
const newUserData = {
school,
photo,
photoone,
address,
}
const newUser = new Teacher(newUserData);
newUser.save()
.then(() => res.json('User Added'))
.catch((err) => {
console.log(err);
});
}
Please see how to solve that?
The route you are trying to POST your form data is not defined please set your route path like this:
router.post('/teacher',upload.fields([{
name: "photo", maxCount: 1
}, {
name: "photoone", maxCount: 1
}
]), (req, res) => {
const school = req.body.school;
const photo = req.files['photo'][0]
const photoone = req.files['photoone'][0]
const address = req.body.address;
const newUserData = {
school,
photo,
photoone,
address,
}
const newUser = new Teacher(newUserData);
newUser.save()
.then(() => res.json('User Added'))
.catch((err) => {
console.log(err);
});
})
...

Multer not able to get the filename

I'm not able to get the filename or path from Multer. This is what I've done so far:
uploadcsv.js
const fileUpload = multer({
limits: 500000,
storage:multer.diskStorage({
destination: (req, file, cb) =>{
cb(null,'upload/csv')
},
filename: (req, file, cb) =>{
const ext = MIME_TYPE_MAP[file.mimetype]
cb(null, uuid + '.' + ext)
},
fileFilter: (req, file, cb) =>{
const isValid = !!MIME_TYPE_MAP[file.mimetype]
let error = isValid ? null : new Error('Invalid mime type')
cb(error, isValid)
}
})
})
Then the route api:
router.post('/contact/importcontact', JWTAuthenticationToken, fileUpload.single('csv'), async (req, res) => {
console.log(req.body)
console.log(req.file.filename)
const csvFilePath = req.file.filename
const stream = fs.createReadStream(csvfile);
const account= await Account.findOne({ acctid: { "$eq": req.body.acctid } })
try {
if (req.file == undefined)
return res.status(400).send({ msg: 'No files were uploaded.' });
csvtojson()
.fromFile(csvFilePath)
.then((jsonObj) => {
console.log(jsonObj);
})
// Async / await usage
const jsonArray = await csvtojson().fromFile(csvFilePath);
res.json({ success: "Uploaded Successfully", status: 200 })
} catch (error) {
res.json({ message: error })
}
})
Lastly, the react importcustomer.js
const handleCSVChange = (e) => {
console.log(e.target.files[0])
setCsvData(e.target.files[0])
setUploadButtonData(e.target.files[0].name)
}
const uploadCSVData = async (e) => {
setLoading(true)
const formData = new FormData();
formData.append("csv", csvData);
console.log(formData)
e.preventDefault()
const response = await Axios.post(process.env.REACT_APP_FETCH_URL + '/api/contact/importcontact', { formData: formData, acctid: lsData.acctid}, { withCredentials: true })
if (response.data.statusCode === "409") {
setMessage(response.data.msg)
setLoading(false)
}
else if (response.data.statusCode === "200") {
setLoading(false)
//history.push('/sources')
}
}
return (
<div className="col-12 grid-margin stretch-card">
<div className="card">
<div className="card-body">
<h4 className="card-title">Import Customer Data From CSV</h4>
<form className="forms-sample" enctype="multipart/form-data">
<div className="form-group">
<label for="files" className="btn btn-primary">{uploadButtonData}
<input id="files" type="file" name="csv" className="form-control" hidden accept="*.csv" onChange={handleCSVChange} /></label>
</div>
<button className="btn btn-primary" onClick={uploadCSVData} style={{ float: "right", width: "7rem" }} type="button">
{loading && <i className="fa fa-refresh fa-spin"></i>}
Upload CSV</button>
<div className="mt-3" style={{ textAlign: "center" }}>
<span id="msg" style={{ color: "red" }}>{message}</span>
</div>
</form>
</div>
</div>
</div>
)
Though I'm able to console.log(req.body) and console.log(e.target.files[0]) and getting the acctid and filename but returned empty for the console.log(formData) and console.log(req.file.filename) returned undefined. What have I missed? Many thanks in advance and greatly appreciate any helps. Thanks again
I have managed to solves this by appending the acctid to formData:
const formData = new FormData();
formData.append("csv", csvData);
formData.append("accctid", lsData.acctid);
const response = await Axios.post(process.env.REACT_APP_FETCH_URL + '/api/contact/importcontact', formData, { withCredentials: true })

POST http://localhost:3000/upload 404 (Not Found)

I'm working on a file upload app and have run into an issue. When submitting to upload the file, I get a post 404 error in the console. The full code is here. I'm assuming that there's an issue in the file upload component but can't seem to understand the problem here.
FileUpload.js
import React, { useState } from "react";
import axios from "axios";
export const FileUpload = () => {
const [file, setFile] = useState("");
const [filename, setFilename] = useState("Choose File");
const [uploadedFile, setUploadedFile] = useState({});
const onChange = (e) => {
setFile(e.target.files[0]);
setFilename(e.target.files[0].name);
};
const onSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("file", file);
try {
const res = await axios.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
const { fileName, filePath } = res.data;
setUploadedFile({ filename, filePath });
} catch (err) {
if (err.response.status === 500) {
console.log("There was a problem with the server");
} else {
console.log(err.response.data.msg);
}
}
};
return (
<>
<form onSubmit={onSubmit}>
<div class="custom-file">
<input
type="file"
class="custom-file-input"
id="customFile"
onChange={onChange}
/>
<label class="custom-file-label" for="customFile">
{filename}
</label>
</div>
<input
type="submit"
value="Upload"
className="btn btn-primary btn-block mt-4"
/>
</form>
</>
);
};

Cannot parse to get the token

For some reason I cannot get the token from the localstorage in order to make the request, it says that there is no token. I am using cookie parser. I am trying to create a new category for my shop. It is not recognizing the token, although it is here.
here is my client:
adminDashoard.js
import { useState } from 'react';
import { createCategory } from './api/category';
import isEmpty from 'validator/lib/isEmpty';
import { showErrorMsg, showSuccessMsg } from './helpers/message';
import { showLoading } from './helpers/Loading'
export default function AdminDashboard() {
const [category, setCategory] = useState('');
const [errorMsg, setErrorMsg] = useState('');
const [successMsg, setSuccessMsg] = useState('');
const [loading, setLoading] = useState(false);
const handleMessages= evt =>{
setErrorMsg('');
setSuccessMsg('');
}
const handleCategoryChange = (evt) => {
setErrorMsg('');
setSuccessMsg('');
setCategory(evt.target.value);
}
const handleCategorySubmit = (evt) => {
evt.preventDefault();
if (isEmpty(category)) {
setErrorMsg('Please enter a category')
} else {
const data = { category }
setLoading(true);
createCategory(data)
.then(response => {
setLoading(false);
setSuccessMsg(response.data.successMessage)
})
.catch(err => {
setLoading(false);
setErrorMsg(err.response.data.errorMessage)
console.log(err)
})
}
};
function ShowHeader() {
return (
<div className='bg-dark text-white py-4'>
<div className='container'>
<div className='row'>
<div className='col-md-6'>
<h1>
<i className='fas fa-home'> Dashboard</i>
</h1>
</div>
</div>
</div>
</div>
)
}
function ShowActionBtns() {
return (
<div className='bg-light my-2'>
<div className='container'>
<div className='row pb-3'>
<div className='col-md-4 my-1 '>
<button
className='btn btn-outline-info btn-block'
data-toggle='modal'
data-target='#addCategoryModal'>
<i className=' fas fa-plus'>Add Category</i>
</button>
</div>
<div className='col-md-4 my-1 '>
<button className='btn btn-outline-danger btn-block'>
<i className=' fas fa-plus'>Add Products</i>
</button>
</div>
<div className='col-md-4 my-1 '>
<button className='btn btn-outline-success btn-block'>
<i className=' fas fa-plus'>Add Blog</i>
</button>
</div>
</div>
</div>
</div>
)
}
function ShowCategoryModal() {
return (
<div id='addCategoryModal' className='modal' onClick={handleMessages}>
<div className='modal-dialog modal-dialog-centered modal-lg'>
<div className='modal-content'>
<form onSubmit={handleCategorySubmit}>
<div className='modal-header bg-info text-white'>
<h5 className='modal-title'>Add Category</h5>
<button className='close' data-dismiss='modal'>
<span>
<i className='fas fa-times'></i>
</span>
</button>
</div>
<div className='modal-body my-2'>
{errorMsg && showErrorMsg(errorMsg)}
{successMsg && showSuccessMsg(successMsg)}
{
loading ? (
<div className='text-center'>{showLoading()}</div>
) : (
<>
<label className='text-secondary'> Category</label>
<input
type='text'
className='form-control'
name='category'
value={category}
onChange={handleCategoryChange}
/>
</>
)
}
</div>
<div className='modal-footer'>
<button data-dismiss='modal' className='btn btn-secondary'>Close</button>
<button className='btn btn-info' type='submit'>Submit</button>
</div>
</form>
</div>
</div>
</div>
)
}
return <div>
{ShowHeader()}
{ShowActionBtns()}
{ShowCategoryModal()}
</div>
}
Here is my api file:
import axios from "axios"
export const createCategory = async (formData) => {
const config = {
headers: {
'Content-Type': 'application/json'
},
};
const response = await axios.post('http://localhost:5000/api/category', formData, config);
return response;
}
on the server side,
here is my server.js :
const express=require('express');
const app= express();
const cors=require('cors');
const connectDB= require('./database/db');
const morgan= require('morgan');
const authRoutes= require ('./routes/auth')
const categoryRoutes = require ('./routes/category');
const cookieParser = require('cookie-parser')
//middleware
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(cookieParser());
app.use('/api/auth', authRoutes);
app.use('/api/category', categoryRoutes);
connectDB();
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));
app.get('/', (req, res) =>{
res.send(' hello server')
})
here is my route file :
const express = require('express');
const router = express.Router();
const categoryController = require('../routes/controllers/category');
const {authenticatateJWT} = require('./middleware/authenticator');
router.post('/', authenticatateJWT, categoryController.create);
module.exports = router;
here is my controller:
exports.create = (req, res)=>{
console.log(req.user);
setTimeout(() =>{
res.json({
successMessage: `${req.body.category} was created!`
});
}, 5000)
}
here is my middleware:
const jwt = require('jsonwebtoken');
const { jwtSecret } = require('../../config/keys');
exports.authenticatateJWT = (req, res, next) => {
const token = req.cookies.token;
console.log(token);
if (!token) {
return res.status(401).json({
errorMessage: 'No token. Authorization denied',
});
}
try {
const decoded = jwt.verify(token, jwtSecret);
req.user = decoded.user;
next();
} catch (err) {
console.log('jwt error:', err)
res.status(401).json({
errorMessage: 'Invalid token',
});
}
};

Angular2+ : what is the simplest way to implement a simple file upload? my code is terribly not working

i made a mean stack crud board and it works well. (angular2+, node.js, express, mongoDB)
after i tried to add upload function and it doesn' work.
this is error message.
compiler.js:486 Uncaught Error: Template parse errors:
Can't bind to 'uploader' since it isn't a known property of 'input'. (" <label for="file">파일</label>
<input type="file" name="single" ng2FileSelect [ERROR ->][uploader]="uploader" >
<button type="button" (click)="uploader.uploadAll()">
"): ng:///BoardModule/BoardCreateComponent.html#22:57
I've done making upload function by jsp but it's way more complicated.
do you have any idea of making upload function?
i would like to create a post with title, author, file 3 inputs
i uploaded my code github as well.
this is full code in github.
https://github.com/9aram/code-test
board-create.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { BoardService } from '../../services/board.service';
import { Board } from '../../models/Board';
import {FileUploader} from 'ng2-file-upload';
#Component({
selector: 'app-board-create',
templateUrl: './board-create.component.html',
styles: []
})
export class BoardCreateComponent {
//파일 업로드 요청url
uploader:FileUploader = new FileUploader({
url:'http://localhost:3000/board-create'
});
fileInfo = {
originalname:'',
filename:''
};
board: any = {};
constructor(private router: Router, private boardService: BoardService) {
//업로드 요청 결과 받아오는 메소드
this.uploader.onCompleteItem = (item, response, status, header) =>{
this.fileInfo=JSON.parse(response);
};
}
saveBoard(boardForm) {
boardForm.form.value.originalname= this.fileInfo.originalname;
boardForm.for.value.filename=this.fileInfo.filename;
this.boardService.insertBoard(this.board)
.subscribe((res: Board) => { this.router.navigate(['/boards']); }, (err) => console.log(err));
}
}
board-create.component.html
<form #boardForm="ngForm" (ngSubmit)="saveBoard(boardForm)">
<div class="field">
<div class="control">
<label for="title">Title</label>
<input required name="title" id="title" [(ngModel)]="board.title" type="text" class="input">
</div>
</div>
<div class="field">
<div class="control">
<label for="author">Author</label>
<input required name="author" id="author" [(ngModel)]="board.author" type="text" class="input">
</div>
</div>
<div class="field">
<div class="control">
<label for="file">파일</label>
<input type="file" name="single" ng2FileSelect [uploader]="uploader" >
<button type="button" (click)="uploader.uploadAll()">
<<span>uploadd..</span>
</button>
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-warning" routerLink="/boards"><i class="fas fa-arrow-left"></i>Back</button>
<button class="button is-link" type="submit" [disabled]="!boardForm.valid">Create</button>
</div>
</div>
</form>
node > api.js
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Board = require('../models/Board.js');
const bodyParser = require('body-parser');
const cors = require('cors');
const upload=require('../util/upload');
// API ROOT ROUTE
router.get('/', (req, res) => {
res.status(200).json({ status: 200, result: 'success' });
});
router.post('/', (req, res) => {
let newBoard = new Board({
title : request.body.title
}),
newBoard.save();
response.type("application/json");
response.send({
result:true
});
});
// GET ALL BoardS
router.get('/board', (req, res, next) => {
Board.find((err, products) => (err) ? next(err) : res.json(products));
});
// GET A Board
router.get('/board/:id', (req, res, next) => {
Board.findById(req.params.id, (err, post) => (err) ? next(err) : res.json(post));
});
// SAVE A Board
router.post('/board', upload.single('file'), (req, res, next) => {
response.type("application/json");
response.send({result:true,
originalname: request.file.originalname,
filename: request.file.filename()});
Board.create(req.body, (err, post) => (err) ? next(err) : res.json(post));
});
module.exports = router;
upload.js
const multer = require('multer');
const storage = multer.diskStorage({
description:function(request, file, cb){
cb(null, __dirname + '/../upload');
}
filename: function(request, file, cb){
let datetimestamp=Date.now();
let originalFileName=file.originalname;
originalFileName=originalFileName.split('.');
let originalName=originalFileName[originalFileName.length - 1];
cb(null, file.filename + '-' + datetimestamp+ '.'+originalName);
}
});
//starage 객체만들어 multer의 멤버 설정
const upload = multer({
storage: storage
})
//외부에서 upload객체 사용할 수 있또록 함
module.exports = upload;
Could you please try to implement the same by checking the below code.
ust call uploadFile(url, file).subscribe() to trigger an upload
import { Injectable } from '#angular/core';
import {HttpClient, HttpParams, HttpRequest, HttpEvent} from '#angular/common/http';
import {Observable} from "rxjs";
#Injectable()
export class UploadService {
constructor(private http: HttpClient) { }
// file from event.target.files[0]
uploadFile(url: string, file: File): Observable<HttpEvent<any>> {
let formData = new FormData();
formData.append('upload', file);
let params = new HttpParams();
const options = {
params: params,
reportProgress: true,
};
const req = new HttpRequest('POST', url, formData, options);
return this.http.request(req);
}
}
You can get further information via below link.
https://appdividend.com/2018/05/25/angular-6-file-upload-tutorial/

Resources