2

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

10
  • Where are you seeing When I click on "upload" button the server returns the value ImageUpload:uploaded: FileItem {u...? Commented May 24, 2017 at 17:36
  • On the console of browser. This log is emitted by the onCompleItem listener that is defined on component. Commented May 24, 2017 at 18:02
  • Totally missed that console.log. Posted what I think may be missing. Assumption is that it is missing and does not exist in those ..... Commented May 24, 2017 at 18:49
  • I've added more info to original message, the .... means code that is irrelevant to this question and could add noise to the question. Thanks for your time Commented May 25, 2017 at 8:18
  • I deleted my answer after I was able to make sure that your backend code was fine. In short with your exact same backend code I am able to make everything. The only thing I had to do was add proxy for CORS. You need those headers for the app that server angular. If using angular-cli try --proxy Commented May 25, 2017 at 16:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.