user5854440
user5854440

Reputation: 281

Multer - Error: Unexpected field

I'm getting a lengthy error when I try to pass my multipart form data to the back end:

Error: Unexpected field
    at makeError (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/lib/make-error.js:12:13)
    at wrappedFileFilter (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/index.js:39:19)
    at Busboy.<anonymous> (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/lib/make-middleware.js:112:7)
    at emitMany (events.js:108:13)
    at Busboy.emit (events.js:182:7)
    at Busboy.emit (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/node_modules/busboy/lib/main.js:31:35)
    at PartStream.<anonymous> (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/node_modules/busboy/lib/types/multipart.js:208:13)
    at emitOne (events.js:77:13)
    at PartStream.emit (events.js:169:7)
    at HeaderParser.<anonymous> (/Users/****/Documents/Programming Projects/JavaScript/Angular/Back-Yard-Brewing/node_modules/multer/node_modules/busboy/node_modules/dicer/lib/Dicer.js:51:16)
    at emitOne (events.js:77:13)

I think I know what the issue is, I just don't know how to solve it. In my code, I use a service to append my multipart form, and then send it to the server. After that, I don't know what the image is named when it arrives at the server. So instead of just naming it "picture", I need to name it something more specific. Problem is, I don't know what. Here's my code:

Front End

            <label>Beer Name</label></br>
            <input ng-model="recipe.alias"></br>
            <label>Image</label></br>
            <input type="file" file-model="recipe.image">
            <label>Category</label></br>
            <select ng-options="beer.alias as beer.alias for beer in beerTypes" ng-model="recipe.selectedCategory" ng-change="filterByCategory(selectedCategory)">
            </select></br>
            <label>Description</label></br>
            <textarea maxlength="500" ng-model="recipe.description" cols="50" rows="5" class="input-box"></textarea></br>
            <p>Character count: {{recipe.description.length}} out of 500</p>
            <label>Instructions</label></br>
            <textarea maxlength="1000" ng-model="recipe.instructions" cols="50" rows="5" class="input-box"></textarea></br>
            <p> Character count: {{recipe.instructions.length}} out of 1000 (Minimum: 500)</p> 
            <button ng-click="createRecipe()" class="button-color btn btn-default">submit</button></br>

Angular

$scope.recipe = {alias: null, selectedCategory: null, description: null, instructions: null, username: null, userID: null, image: null};

$scope.createRecipe = function(){
    authService.getUserInfo(function(user){
        // add the user information to the recipe
        $scope.recipe.username = user.username;
        $scope.recipe.userID = user._id;

    });
    multipartForm.post("/createrecipe", $scope.recipe);
}

Angular Service

.service("multipartForm", ["$http", function($http){
    this.post = function(uploadUrl, data){
        var fd = new FormData();
        for(key in data){
            fd.append(key, data[key]);
        }
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {"Content-Type" : undefined}
        });
    }
}]);

Server File

var express = require("express");
var bodyParser = require("body-parser");
var session = require("express-session");
var multer = require("multer");
var upload = multer({ dest: "./uploads"})
var server = express();


var recipeController = require("./controllers/RecipeController")
var favRecipeController = require("./controllers/FavRecipeController")
var authenticationController = require('./controllers/Authentication');

var passportConfig = require('./config/passport');
var passport = require('passport');

//application configuration
//resave will keep it true

server.sessionMiddleware = session({
    secret            : "123iojojojoiklij",
    resave            : true,
    saveUninitialized : false,
    rolling           : true,
    cookie            : {maxAge: 60000 * 60}
});
server.use(server.sessionMiddleware);

//End Express Session Setup

server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(express.static(__dirname + "/public"));


server.use(passport.initialize());

server.use(passport.session());


server.post("/createrecipe", upload.single("picture"), recipeController.createRecipe);

All help is appreciated.

Upvotes: 3

Views: 2077

Answers (1)

user5854440
user5854440

Reputation: 281

OK, so a shout out to Gandalf the White and ShanShan for the answer:

As it turns out in my server.js, in my post to the server, my single.upload("photo") just needed to be single.upload("image"),, since that's what I had labeled it in my front end. Thank you for all your help.

Lesson learned: even if you are passing a multipart form via object, multer still sees it as what you originally labeled it as.

Upvotes: 1

Related Questions