MongoDB / Express / Node File upload error

I'm working on a Mongo / Node / Express example to help me understand how full stack project chunks fit together. The app is pretty simple: the express server sends a page that the user can use to load the image. Photos are saved and users can use the site to view the uploaded images and view various features.

I haven't started implementing anything related to persistence or Mongo, so I'm pretty sure this is not a problem (which means it is possible). I am using these frameworks / packages:

Node.js: 0.10.33

  • Express: 4.10.7
  • Express-Handlebars: 1.1.0
  • MongoDB: 1.4.28
  • Mongoose: 3.8.21

Bauer: 1.3.12

  • Bootstrap: 3.3.1

The error that I cannot identify appears when I try to upload an image file to the site. When I select an image file and hit submit, I get the following error in the browser ...

Connect

500 TypeError: Cannot read property 'file' of undefined
   at saveImage (/home/dan/development/tuts-book/controllers/image.js:47:37)
   at module.exports.create (/home/dan/development/tuts-book/controllers/image.js:66:9)
   at Layer.handle [as handle_request] (/home/dan/development/tuts-book/node_modules/express/lib/router/layer.js:82:5)
   at next (/home/dan/development/tuts-book/node_modules/express/lib/router/route.js:100:13)
   at Route.dispatch (/home/dan/development/tuts-book/node_modules/express/lib/router/route.js:81:3)
   at Layer.handle [as handle_request] (/home/dan/development/tuts-book/node_modules/express/lib/router/layer.js:82:5)
   at /home/dan/development/tuts-book/node_modules/express/lib/router/index.js:235:24
   at Function.proto.process_params (/home/dan/development/tuts-book/node_modules/express/lib/router/index.js:313:12)
   at /home/dan/development/tuts-book/node_modules/express/lib/router/index.js:229:12
   at Function.match_layer (/home/dan/development/tuts-book/node_modules/express/lib/router/index.js:296:3)

      

Here's the code I'm working with:

Package.json

{
  "name": "tuts-book",
  "version": "1.0.0",
  "description": "Working example from Web Development with MongoDB and Node.js.",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Dan Schatz",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.10.1",
    "cookie-parser": "^1.3.3",
    "errorhandler": "^1.3.2",
    "express": "^4.10.7",
    "express-handlebars": "^1.1.0",
    "method-override": "^2.3.1",
    "moment": "^2.9.0",
    "mongodb": "^1.4.28",
    "mongoose": "^3.8.21",
    "morgan": "^1.5.1"
  }
}

      

Server: server.js

'use strict';

var express = require('express'),
    config = require('./server/configure'),
    app = express();

app.set('port', process.env.PORT || 3300);
app.set('views', __dirname + '/views');

app = config(app);

var server = app.listen(app.get('port'), function() {
    console.log('Server up: http://localhost:' + app.get('port'));
});

      

Route file: routes.js

'use strict';

var home    = require('../controllers/home'),
    image   = require('../controllers/image');

module.exports.initialize = function(app, router) {

    router.get('/', home.index);
    router.get('/images/:image_id', image.index);

    router.post('/images', image.create);
    router.post('/images/:image_id/like', image.like);
    router.post('/images/image_id/comment', image.comment);

    app.use('/', router);
};

      

View Wrapper: main.handlebars

<!DOCTYPE HTML>

<html lang="eng">

    <head>
        <meta charset="UTF-8">

        <title>Tuts Book</title>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
        <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
        <link href="/public/css/styles.css" rel="stylesheet" type="text/css" >
    </head>

    <body>

        <div class="page-header">
            <div class="container">
                <div class="col-md-6">
                    <h1><a href="/">imgPloadr.io</a></h1>
                </div>
            </div>
        </div>

        <div class="container">
            <div class="row">

                <div class="col-sm-8">
                    {{{body}}}
                </div>

                <div class="col-sm-4">
                    {{> stats this }}

                    {{> popular this }}

                    {{> comments this }}
                </div>

            </div>
        </div>

        <div style="border-top: solid 1px #eee; padding-top: 1em;">
            <div class="container">
                <div class="row">
                    <div class="col-sm-12 text-center">
                        <p class="text-muted">Schatz.com | &copy; 2014</p>
                        <p class="text-center">
                            <i class="fa fa-twitter-square fa-2x text-primary"></i>
                            <i class="fa fa-facebook-square fa-2x text-primary"></i>
                        </p>
                    </div>
                </div>
            </div>
        </div>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script src="/public/js/scripts.js" type="text/javascript" ></script>

    </body>
</html>

      

Index type: index.handlebars

<div class="panel panel-primary">

    <div class="panel-heading">
        <h2 class="panel-title">{{ image.title }}</h2>
    </div>

    <div class="panel-body">
        <p>{{ image.description }}</p>
        <div class="col-md-12 text-center">
            <img src="/public/upload/{{ image.filename }}" class="img-thumbnail">
        </div>
    </div>

    <div class="panel-footer">
        <div class="row">
            <div class="col-md-8">
                <button class="btn btn-success" id="btn-like" data-id="{{ image.uniqueId }}"><i
                        class="fa fa-heart"> Like</i></button>
                <strong class="likes-count">{{ image.likes }}</strong> &nbsp; - &nbsp; <i
                    class="fa fa-eye"></i> <strong>{{ image.views }}</strong>
                &nbsp; - &nbsp; Posted: <em class="text-muted">{{ timeago image.timestamp }}</em>
            </div>
        </div>
    </div>
</div>

<div class="panel panel-default">

    <div class="panel-heading">
        <div class="row">
            <div class="col-md-8">
                <strong class="panel-title">Comments</strong>
            </div>
            <div class="col-md-4 text-right">
                <button class="btn btn-default btn-sm" id="btn-comment" data-id="{{ image
                .uniqueId }}"><i class="fa fa-comments-o"> Post Comment...</i></button>
            </div>
        </div>
    </div>

    <div class="panel-body">
        <blockquote id="post-comment">
            <div class="row">

                <form method="post" action="/images/{{ image.uniqueId }}/comment">
                    <div class="form-group col-sm-12">
                        <label class="col-sm-2 control-label" for="name">Name:</label>
                        <div class="col-sm-10">
                            <input class="form-control" type="text" name="name">
                        </div>
                    </div>

                    <div class="form-group col-sm-12">
                        <label class="col-sm-2 control-label" for="email">Email:</label>
                        <div class="col-sm-10">
                            <input class="form-control" type="text" name="email">
                        </div>
                    </div>

                    <div class="form-group col-sm-12">
                        <label class="col-sm-2 control-label" for="comment">Comment:</label>
                        <div class="col-sm-10">
                            <textarea class="form-control" name="comment" rows="2"></textarea>
                        </div>
                    </div>

                    <div class="form-group col-sm-12">
                        <div class="col-sm-12 text-right">
                            <button type="submit" id="comment-btn" class="btn btn-success"
                                    type="button"><i class="fa fa-comment"></i> Post</button>
                        </div>
                    </div>
                </form>
            </div>
        </blockquote>

        <ul class="media-list">
            {{#each comments}}
            <li class="media">
                <a class="pull-left" href="#">
                    <img class="media-object img-circle" src="http://www.gravatar.com/avatar/{{
                    gravatar }}?d=monsterid&s=45">
                </a>
                <div class="media-body">
                    {{ comment }}
                    <br/><strong class="media-heading">{{ name }}</strong> <small
                        class="text-muted">{{ timeago timestamp }}</small>
                </div>
            </li>
            {{/each}}
        </ul>

    </div>
</div>

      

I spent a couple of days exploring many different possibilities (including the new Express 4.0 content), but I ran out of leaders.

I also found this post: req.files question , but I already have this solution in my HTML.

If you have any thoughts, I am very grateful for the help. And if there is any relevant code that I have not included, let me know and I will add it. Thanks again.

+3


source to share


1 answer


Express 4 incompatible multiplayer messages, you will need to use Multer or Busboy. Have a look at GridFS as you need to store the pic in the mongo database associated with the user and can retrieve it later.



I personally would just have another server to download the pic instead, so you just need to process the link as text using your node.js - mongodb installation. Take a look at this explaining it step by step: https://devcenter.heroku.com/articles/s3-upload-node

0


source







All Articles