I'm trying to implement this library to upload images to a folder server:
When I click on "upload" button the server returns inmediately to the listener this.uploader.onCompleteItem
on my fileUpload.ts
component:
ImageUpload:uploaded: FileItem {url: "http://127.0.0.1:5000/api/uploadPhoto", headers: Array(0), withCredentials: false, formData: Array(0), isReady: false…}alias: "file"file: FileLikeObjectformData: Array(0)headers: Array(0)index: undefinedisCancel: falseisError: falseisReady: falseisSuccess: trueisUploaded: trueisUploading: falsemethod: "POST"options: ObjectautoUpload: falsedisableMultipart: falsefilters: Array(1)isHTML5: trueitemAlias: "file"removeAfterUpload: falseurl: "http://127.0.0.1:5000/api/uploadPhoto"__proto__: Objectprogress: 100some: Fileuploader: FileUploaderurl: "http://127.0.0.1:5000/api/uploadPhoto"withCredentials: false_file: File_xhr: XMLHttpRequest__proto__: Object 200 "uploaded"
But the file is not present on server. What would be doing wrong?
This is my backend: Server.js
var express = require("express"),
app = express(),
cors = require('cors'),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
http = require("http"),
multer = require('multer');
server = http.createServer(app),
router = express.Router()
.....
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Methods", "POST, PUT, OPTIONS, DELETE, GET");
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
next();
});
//NEW
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cors());
app.use(methodOverride());
app.use(passport.initialize());
app.use(busboyBodyParser());
//
app.use('/api', router);
var upload = multer({dest: "./uploads/"}).single('file');
router.post("/uploadPhoto",function (req, res) {
upload(req, res, function (err) {
if (err) {
console.log(err.toString())
return res.status(422).json("an Error occured")
}
console.log("done")
return res.status(200).json("uploaded")
})
}
);
This is my Frontend
fileUpload.ts
import { FileUploader } from 'ng2-file-upload';
...
public uploader:FileUploader;
constructor() {
this.uploader = new FileUploader({url: this.URL + "uploadPhoto", itemAlias: 'file'});
this.uploader.onBeforeUploadItem = (item) => {
item.withCredentials = false;
}
this.uploader.onCompleteItem = (item:any, response:any, status:any, headers:any) => {
console.log("ImageUpload:uploaded:", item, status, response);
};
}
fileUpload.html
....
<input name="file" type="file" ng2FileSelect [uploader]="uploader"/>
<button type="button" class="btn btn-success btn-xs"
(click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">
<span class="glyphicon glyphicon-upload"></span> upload
</button>
.....
Systemjs.config.js
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles//
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'@angular/material': 'npm:@angular/material/bundles/material.umd.js',
'hammerjs': 'npm:hammerjs/hammer.js',
'ngx-sharebuttons': 'node_modules/ngx-sharebuttons/bundles/ngx-sharebuttons.umd.js',
'ngx-cookie': 'npm:ngx-cookie/bundles/ngx-cookie.umd.js',
'ng2-file-upload': 'npm:ng2-file-upload',
'@agm/core': 'node_modules/@agm/core/core.umd.js',
'@angular/animations': 'node_modules/@angular/animations/bundles/animations.umd.min.js',
'@angular/animations/browser':'node_modules/@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser/animations': 'node_modules/@angular/platform-browser/bundles/platform-browser-animations.umd.js'
//
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js',
main: 'Rx.js'
},
'ng2-file-upload': {
main: 'ng2-file-upload.js',
defaultExtension: 'js'
}
}
});
})(this);
app.module
import { FileSelectDirective, FileDropDirective } from 'ng2-file-upload';
....
declarations:[FileSelectDirective,.....
package.json of my frontend
{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
},
"license": "ISC",
"dependencies": {
"@agm/core": "^1.0.0-beta.0",
"@angular/animations": "^4.1.2",
"@angular/common": "4.1.3",
"@angular/compiler": "4.1.3",
"@angular/compiler-cli": "4.1.3",
"@angular/core": "4.1.3",
"@angular/forms": "4.1.3",
"@angular/http": "4.1.3",
"@angular/material": "2.0.0-beta.5",
"@angular/platform-browser": "4.1.3",
"@angular/platform-browser-dynamic": "4.1.3",
"@angular/router": "4.1.3",
"@angular/upgrade": "4.1.3",
"body-parser": "^1.15.2",
"bootstrap": "^3.3.6",
"core-js": "^2.4.1",
"express": "^4.14.0",
"hammerjs": "^2.0.8",
"method-override": "^2.3.6",
"ng2-file-upload": "^1.2.0",
"ngx-cookie": "^1.0.0",
"ngx-sharebuttons": "^3.0.0",
"node-sass": "^4.5.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.4.0",
"systemjs": "0.20.12",
"zone.js": "^0.8.5"
},
"devDependencies": {
"@types/hammerjs": "^2.0.34",
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"typescript": "^2.1.6",
"typings": "^2.1.0"
}
}
package.json backend
{
"name": "Backend",
"version": "0.0.0",
"description": "Generated with Eclipse npm Tools",
"main": "index.js",
"author": "",
"license": "ISC",
"dependencies": {
"agenda": "^0.9.1",
"async": "^2.3.0",
"bluebird": "^3.4.7",
"body-parser": "^1.16.1",
"busboy-body-parser": "^0.3.0",
"crypto": "0.0.3",
"email-verification": "^0.4.6",
"express": "^4.14.1",
"gridfs-stream": "^1.1.1",
"method-override": "^2.3.7",
"mongoose": "^4.8.5",
"multer": "^1.3.0",
"mysql": "^2.11.1",
"nconf": "^0.8.4",
"oauth2orize": "^1.7.0",
"passport": "^0.3.2",
"passport-http": "^0.3.0",
"passport-http-bearer": "^1.0.1",
"passport-oauth2-client-password": "^0.1.2"
}
}
EDIT2:
I've half solved the problem with this:
var express = require("express"),
app = express(),
cors = require('cors'),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
http = require("http"),
multer = require('multer');
server = http.createServer(app),
router = express.Router()
.....
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Methods", "POST, PUT, OPTIONS, DELETE, GET");
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
next();
});
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
console.log("aha " + file.originalname);
cb(null, file.originalname)
}
})
var upload = multer().single('file')
//THIS IS MANDATORY, WITHOUT THIS NOW WORK
app.use(multer({
storage:storage
}).single('file'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cors());
app.use(methodOverride());
app.use(passport.initialize());
app.use(busboyBodyParser());
//
app.use('/api', router);
router.post("/uploadPhoto", function(req, res) {
console.log(req.file);
upload(req,res,function(err){
if(err){
res.status(500).json({'success':false});
return;
}
res.status(200).json({'success':true});
});
});
The app.use(multer({storage:storage}).single('file'));
appears to be the key. But I pretty new and I dont know why
Also With 'multiple' and .array('file',12) isn't work
I've founded a related question on multer github page with the same problem