Error: Multipart: Boundary not found
I want to add file with some text files with angular: here's my service:
src/app/services/web.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data'
})
}
@Injectable({
providedIn: 'root'
})
export class WebService {
devUri:string = 'http://localhost:4000';
constructor(private http:HttpClient) { }
post(uri:string, object: Object){
console.log(object);
return this.http.post(`${this.devUri}/${uri}`, object, httpOptions);
}
}
It shows Error: Multipart: Boundary not found
Before somebody write "Just remove 'Content-Type': 'multipart/form-data' it will work it won't!
When I remove this, then my req.files = []( there's also some variations where this is equal undefined).
Here's my route( not full, but there's nothing more is needed):
routes/api/messages.js
const { initStorage, initUpload } = require('../../modules/multerModule');
const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db);
gfs.collection(collectionName);
});
const collectionName = 'messages';
const bucketName = 'messages';
const storage = initStorage(conn, bucketName);
const upload = initUpload(storage);
router.post('/', upload.any(), (req, res) => {
console.log(req.files);
console.log(req.body);
...
}
Here's my functions from multerModule(it all works on react/redux, app, but don't work on Angular):
modules/multerModule.js:
const path = require('path');
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
// Create storage engine
const initStorage = (conn, bucketName) => new GridFsStorage({
db: conn,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: bucketName
};
resolve(fileInfo);
});
});
}
});
// Create upload module
const initUpload = (storage) => multer({
storage: storage,
fileFilter: function (req, file, callback) {
const ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
}
});
module.exports = { initStorage, initUpload };
Ofcourse later when I try to use req.files(destructurize or whatever else) I get error, because it's undefined or empty array. And in req.body, theres also shows up messages field:
[Object: null prototype] {
messages: '[object File]',
content: 'dsada',
path: 'undefined',
fileImage: 'true'
}
The last two things are server.js and onSubmit function:
server.js
...
const bodyParser = require('body-parser');
// #6 Initialize an Express application
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(bodyParser.json({limit: '50mb', extended: true}));
const db = process.env.mongoURI;
// Connect to Mongo
mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false }) // Adding new mongo url parser
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
...
OnSubmit function:
src/app/components/Message/add-message/add-message.ts
onSubmit() {
if( this.fileImage){
const message = new FormData();
console.log(this.files[0]);
message.append('messages', this.files);
console.log(typeof(JSON.stringify(this.fileImage)));
message.append('content', this.content);
message.append('fileImage', JSON.stringify(this.fileImage));
this.addMessage.emit(message);
}
else{
const message = {
content: this.content,
fileImage: this.fileImage,
path: this.path
}
this.addMessage.emit(message);
}
}
After some tries I get another error( now I don't include httpOptions in HttpClient module and the file data appended to FormData() is identical as this in react-redux/node app):
Error: The database connection must be open to store files
at GridFSStorage._handleFile
The problem is that the same code works correctly in redux app, but not in angular.
Ok, I found something when I console.log here:
I found one difference:
On angular app I found this:
I have three models: user, post and message.
On react app I found that:
and it's correct, so it looks like my storage doesn't includes all models routes. And I don't know why, but it seems, that's the problem. The same goes about modelSchemas properties. Even when I comment this route( app.use(/auth) ) it still includes only userSchema and UserModel.
And after connection is server.js I logged the "promise".
And get only one model and schema(even I have three models: post, user, message):