0

I want to upload a file that is more than 16MB to my database Mongo. On the front end part, I use ng-file-upload module (https://github.com/danialfarid/ng-file-upload). On the back-end side, i use connect-busboy and gridfs-stream modules

I get the following error: POST /api/files/ 500 3.084 ms - 1992 Error: Unsupported content type: application/json;charset=utf-8 at Busboy.parseHeaders (C:...\node_modules\busboy\lib\main.js:68:9) at new Busboy...

When the file is selected, the function $scope.uploadFile($file) of my controller is called which is calling a backend server api with a post method. The issue seems to be on the api call part.

I have 2 questions: - what am I doing wrong? and is there a better way to do it?

Here how my code looks like:

front-end

html page

<label class="label-form" for="image">Upload Picture:</label>
<input type="file" id="image" name="image" ngf-select="uploadFile($files)" ngf-max-size="1MB" ng-model="image" ngf-pattern="'image/*'" accept="image/*" ngf-resize="{width: 100, height: 100}" />

then I have my controller.js

var appControllers = angular.module('appControllers', ['ngFileUpload']);

appControllers.controller('appUploadController',['$scope','$location','Upload', function($scope, $location, Upload){
  $scope.uploadFile = function($file) {
    Upload.upload($file)
      .then(function (resp) {
        console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
    }, function (resp) {
      console.log('Error status: ' + resp.status);
    }, function (evt) {
      var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
      console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
    });
   };
}]);

then my service.js file where the post api call to api/files/ is made:

var appServices = angular.module('appServices',[]);

appServices.factory('Upload',['$http',function($http){
    return{
        upload : function(file){
            return $http.post('/api/files/', file);
        }
    }
}]);

Back-end Now on the backend-side, I have my app.js file, the api.js file and the database configuration file as below:

the api.js file:

var Busboy = require('busboy');

app.post('/api/files',function(req,res,next){
  console.log("and the call has been successful");
  var busboy = new Busboy({
	headers: req.headers
  });

  busboy.on('error', function(err) {
    console.log(err);
  });
  
  busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
    db.uploadFile(req.files.file.name); // call the function to use gridfs	
  });

  busboy.on('finish', function() {
    console.log('finish');
  });
 }

app.js

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var busboy = require('busboy');

var app = express();

var db = require('./app/config/database'); //load the config of the database mongolab
db.init(app);

// view engine setup - configure
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
 
// define middleware
app.use(express.static(__dirname + '/views'));
app.use(bodyParser.json()); // support json encoded bodies
app.use(busboy());
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use(morgan('dev')); // log every request to the console

// define routes
require('./app/routes/routes')(app);
require('./app/api/api')(app, db);

app.listen(3000);

here is my database config file

var mongoose = require('mongoose'); //library for the mongo database
var Grid = require('gridfs-stream');
var fs = require('fs');
var conn = mongoose.connection;

exports.init = function(app) {  
  //connection to the mongo database
  var  uri ="mongodb://...";
  Grid.mongo = mongoose.mongo;
  mongoose.connect(uri, {server:{auto_reconnect:true}});

  conn.once('open', function() {
    var gfs = Grid(conn.db);
    app.set('gridfs', gfs);
    console.log('connection open and the mongo db URI is' +uri);
  });
};

exports.uploadFile = function(file){
  var gfs = Grid(conn.db);
  var file_name = file.name;

  var writestream = gfs.createWriteStream({
        filename: file_name,
        mode:"w",
        content_type: part.mimetype
    });
   
    fs.createReadStream(url_image).pipe(writestream);
 
    writestream.on('close', function (file) {
        console.log(file.filename + 'Written To DB');
    });
};

3
  • In your html part you have specified 'ngf-max-size="1MB"' and you are uploading file of 16 MB Commented Oct 11, 2015 at 9:18
  • true, but i reuse the same function for all my files uploads so in this very specific first case, the file may be below the 16MB but I want to have one upload mechanism for all my file uploads. Commented Oct 11, 2015 at 9:23
  • how to modify the provided code for excel data dump to mongodb Commented Apr 19, 2016 at 15:51

1 Answer 1

2

I think problem with naming. Ng-file-upload use service name Update and you use your factory with name Update too and this is a problem - you use your factory to send file and this is a mistake.

You should use upload mechanism from Ng-file-upload, so remove your Upload Factory.

Your code will be look the same, because you use good naming, you add only url param;)

var appControllers = angular.module('appControllers', ['ngFileUpload']);

appControllers.controller('appUploadController',['$scope','$location','Upload', function($scope, $location, Upload){
  $scope.uploadFile = function($file) {
   Upload.upload({
            url: 'api/files',
            data: {file: $file}
        })
      .then(function (resp) {
        console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
    }, function (resp) {
      console.log('Error status: ' + resp.status);
    }, function (evt) {
      var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
      console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
    });
   };
}]);
Sign up to request clarification or add additional context in comments.

Comments

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.