db在使用nodejs的mongodb中没有定义

时间:2016-02-26 15:39:42

标签: node.js mongodb

大家好我在这三种方法中有三个javascript文件(mongomart.js,items.js和cart.js)mongomart.js是驱动方法,其中包含配置和所有其他东西。当我运行“node mongomart.js “跟随错误来了。

        ReferenceError: db is not defined
           at ItemDAO.getCategories (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\items.js:48:14)
           at C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\mongomart.js:72:15
           at Layer.handle [as handle_request] (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\layer.js:95:5)
           at next (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\route.js:131:13)
           at Route.dispatch (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\route.js:112:3)
           at Layer.handle [as handle_request] (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\layer.js:95:5)
           at C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\index.js:277:22
           at Function.process_params (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\index.js:330:12)
           at next (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\index.js:271:10)
           at Function.handle (C:\Users\Lalit\Desktop\final_project.9265ac2868d2\lab_0\mongomart\mongomart\node_modules\express\lib\router\index.js:176:3)

    Here is all Js files
    mongomart.js

        var express = require('express'),
        bodyParser = require('body-parser'),
        nunjucks = require('nunjucks'),
        MongoClient = require('mongodb').MongoClient,
        assert = require('assert'),
        ItemDAO = require('./items').ItemDAO,
        CartDAO = require('./cart').CartDAO;


    // Set up express
    app = express();
    app.set('view engine', 'html');
    app.set('views', __dirname + '/views');
    app.use('/static', express.static(__dirname + '/static'));
    app.use(bodyParser.urlencoded({ extended: true }));

           var env = nunjucks.configure('views', {
        autoescape: true,
        express: app
    });

    var nunjucksDate = require('nunjucks-date');
    nunjucksDate.setDefaultFormat('MMMM Do YYYY, h:mm:ss a');
    env.addFilter("date", nunjucksDate);

    var ITEMS_PER_PAGE = 5;

    // Hardcoded USERID for use with the shopping cart portion
    var USERID = "558098a65133816958968d88";

    MongoClient.connect('mongodb://localhost:27017/mongomart', function(err, db) {
        "use strict";

        assert.equal(null, err);
        console.log("Successfully connected to MongoDB.");

        var items = new ItemDAO(db);
        var cart = new CartDAO(db);

        var router = express.Router();

        // Homepage
        router.get("/", function(req, res) {
            "use strict";

            var page = req.query.page ? parseInt(req.query.page) : 0;
            var category = req.query.category ? req.query.category : "All";

            items.getCategories(function(categories) {

                items.getItems(category, page, ITEMS_PER_PAGE, function(pageItems) {

                    items.getNumItems(category, function(itemCount) {

                        var numPages = 0;
                        if (itemCount > ITEMS_PER_PAGE) {
                            numPages = Math.ceil(itemCount / ITEMS_PER_PAGE);
                        }

                        res.render('home', { category_param: category,
                                             categories: categories,
                                             useRangeBasedPagination: false,
                                             itemCount: itemCount,
                                             pages: numPages,
                                             page: page,
                                             items: pageItems });

                    });
                });
            });
        });


        router.get("/search", function(req, res) {
            "use strict";

            var page = req.query.page ? parseInt(req.query.page) : 0;
            var query = req.query.query ? req.query.query : "";

            items.searchItems(query, page, ITEMS_PER_PAGE, function(searchItems) {

                items.getNumSearchItems(query, function(itemCount) {

                    var numPages = 0;

                    if (itemCount > ITEMS_PER_PAGE) {
                        numPages = Math.ceil(itemCount / ITEMS_PER_PAGE);
                    }

                    res.render('search', { queryString: query,
                                           itemCount: itemCount,
                                           pages: numPages,
                                           page: page,
                                           items: searchItems });

                });
            });
        });


        router.get("/item/:itemId", function(req, res) {
            "use strict";

            var itemId = parseInt(req.params.itemId);

            items.getItem(itemId, function(item) {
                console.log(item);

                if (item == null) {
                    res.status(404).send("Item not found.");
                    return;
                }

                var stars = 0;
                var numReviews = 0;
                var reviews = [];

                if ("reviews" in item) {
                    numReviews = item.reviews.length;

                    for (var i=0; i<numReviews; i++) {
                        var review = item.reviews[i];
                        stars += review.stars;
                    }

                    if (numReviews > 0) {
                        stars = stars / numReviews;
                        reviews = item.reviews;
                    }
                }

                items.getRelatedItems(function(relatedItems) {

                    console.log(relatedItems);
                    res.render("item",
                               {
                                   userId: USERID,
                                   item: item,
                                   stars: stars,
                                   reviews: reviews,
                                   numReviews: numReviews,
                                   relatedItems: relatedItems
                               });
                });
            });
        });


        router.post("/item/:itemId/reviews", function(req, res) {
            "use strict";

            var itemId = parseInt(req.params.itemId);
            var review = req.body.review;
            var name = req.body.name;
            var stars = parseInt(req.body.stars);

            items.addReview(itemId, review, name, stars, function(itemDoc) {
                res.redirect("/item/" + itemId);
            });
        });


        /*
         *
         * Since we are not maintaining user sessions in this application, any interactions with 
         * the cart will be based on a single cart associated with the the USERID constant we have 
         * defined above.
         *
         */
        router.get("/cart", function(req, res) {
            res.redirect("/user/" + USERID + "/cart");
        });


        router.get("/user/:userId/cart", function(req, res) {
            "use strict";

            var userId = parseInt(req.params.userId);
            cart.getCart(userId, function(userCart) {
                var total = cartTotal(userCart);
                res.render("cart",
                           {
                               userId: userId,
                               updated: false,
                               cart: userCart,
                               total: total
                           });
            });
        });


        router.post("/user/:userId/cart/items/:itemId", function(req, res) {
            "use strict";

            var userId = parseInt(req.params.userId);
            var itemId = parseInt(req.params.itemId);

            var renderCart = function(userCart) {
                var total = cartTotal(userCart);
                res.render("cart",
                           {
                               userId: userId,
                               updated: true,
                               cart: userCart,
                               total: total
                           });
            };

            cart.itemInCart(userId, itemId, function(item) {
                if (item == null) {
                    items.getItem(itemId, function(item) {
                        item.quantity = 1;
                        cart.addItem(userId, item, function(userCart) {
                            renderCart(userCart);
                        });

                    });
                } else {
                    cart.updateQuantity(userId, itemId, item.quantity+1, function(userCart) {
                        renderCart(userCart);
                    });
                }
            });
        });


        router.post("/user/:userId/cart/items/:itemId/quantity", function(req, res) {
            "use strict";

            var userId = parseInt(req.params.userId);
            var itemId = parseInt(req.params.itemId);
            var quantity = parseInt(req.body.quantity);

            cart.updateQuantity(userId, itemId, quantity, function(userCart) {
                var total = cartTotal(userCart);
                res.render("cart",
                           {
                               userId: userId,
                               updated: true,
                               cart: userCart,
                               total: total
                           });
            });
        });


        function cartTotal(userCart) {
            "use strict";

            var total = 0;
            for (var i=0; i<userCart.items.length; i++) {
                var item = userCart.items[i];
                total += item.price * item.quantity;
            }

            return total;
        }


        // Use the router routes in our application
        app.use('/', router);

        // Start the server listening
        var server = app.listen(3000, function() {
            var port = server.address().port;
            console.log('Mongomart server listening on port %s.', port);
        });

    });

    **items.js**

  var MongoClient = require('mongodb').MongoClient,
        assert = require('assert');


    function ItemDAO(database) {
        "use strict";

        this.db = database;

        this.getCategories = function(callback) {
            "use strict";

            /*
            * TODO-lab1A
            *
            * LAB #1A: 
            * Create an aggregation query to return the total number of items in each category. The
            * documents in the array output by your aggregation should contain fields for 
            * "_id" and "num". HINT: Test your mongodb query in the shell first before implementing 
            * it in JavaScript.
            *
            * Ensure categories are organized in alphabetical order before passing to the callback.
            *
            * Include a document for category "All" in the categories to pass to the callback. All
            * should identify the total number of documents across all categories.
            *
            */

            var categories = [];
            var category = 
                 db.collection('item').aggregate([{$group: {_id: "$category", num: {$sum: 1}}},{$sort:{_id:1}}]);

错误出现在上面一行

            categories.push(category)

            // TODO-lab1A Replace all code above (in this method).

            callback(categories);
        }


        this.getItems = function(category, page, itemsPerPage, callback) {
            "use strict";

            /*
             * TODO-lab1B
             *
             * LAB #1B: 
             * Create a query to select only the items that should be displayed for a particular
             * page. For example, on the first page, only the first itemsPerPage should be displayed. 
             * Use limit() and skip() and the method parameters: page and itemsPerPage to identify 
             * the appropriate products. Pass these items to the callback function. 
             *
             * Do NOT sort items. 
             *
             */

            var pageItem = this.createDummyItem();
            var pageItems = [];
            for (var i=0; i<5; i++) {
                pageItems.push(pageItem);
            }

            // TODO-lab1B Replace all code above (in this method).

            callback(pageItems);
        }


        this.getNumItems = function(category, callback) {
            "use strict";

            var numItems = 0;

            /*
             * TODO-lab1C
             *
             * LAB #1C: Write a query that determines the number of items in a category and pass the
             * count to the callback function. The count is used in the mongomart application for
             * pagination. The category is passed as a parameter to this method.
             *
             * See the route handler for the root path (i.e. "/") for an example of a call to the
             * getNumItems() method.
             *
             */

            callback(numItems);
        }


        this.searchItems = function(query, page, itemsPerPage, callback) {
            "use strict";

            /*
             * TODO-lab2A
             *
             * LAB #2A: Using the value of the query parameter passed to this method, perform
             * a text search against the item collection. Do not sort the results. Select only 
             * the items that should be displayed for a particular page. For example, on the 
             * first page, only the first itemsPerPage matching the query should be displayed. 
             * Use limit() and skip() and the method parameters: page and itemsPerPage to 
             * select the appropriate matching products. Pass these items to the callback 
             * function. 
             *
             * You will need to create a single text index on title, slogan, and description.
             *
             */

            var item = this.createDummyItem();
            var items = [];
            for (var i=0; i<5; i++) {
                items.push(item);
            }

            // TODO-lab2A Replace all code above (in this method).

            callback(items);
        }


        this.getNumSearchItems = function(query, callback) {
            "use strict";

            var numItems = 0;

            /*
            * TODO-lab2B
            *
            * LAB #2B: Using the value of the query parameter passed to this method, count the
            * number of items in the "item" collection matching a text search. Pass the count
            * to the callback function.
            *
            */

            callback(numItems);
        }


        this.getItem = function(itemId, callback) {
            "use strict";

            /*
             * TODO-lab3
             *
             * LAB #3: Query the "item" collection by _id and pass the matching item
             * to the callback function.
             *
             */

            var item = this.createDummyItem();

            // TODO-lab3 Replace all code above (in this method).

            callback(item);
        }


        this.getRelatedItems = function(callback) {
            "use strict";

            this.db.collection("item").find({})
                .limit(4)
                .toArray(function(err, relatedItems) {
                    assert.equal(null, err);
                    callback(relatedItems);
                });
        };


        this.addReview = function(itemId, comment, name, stars, callback) {
            "use strict";

            /*
             * TODO-lab4
             *
             * LAB #4: Add a review to an item document. Reviews are stored as an 
             * array value for the key "reviews". Each review has the fields: "name", "comment", 
             * "stars", and "date".
             *
             */

            var reviewDoc = {
                name: name,
                comment: comment,
                stars: stars,
                date: Date.now()
            }

            var dummyItem = this.createDummyItem();
            dummyItem.reviews = [reviewDoc];
            callback(dummyItem);
        }


        this.createDummyItem = function() {
            "use strict";

            var item = {
                _id: 1,
                title: "Gray Hooded Sweatshirt",
                description: "The top hooded sweatshirt we offer",
                slogan: "Made of 100% cotton",
                stars: 0,
                category: "Apparel",
                img_url: "/img/products/hoodie.jpg",
                price: 29.99,
                reviews: []
            };

            return item;
        }
    }


    module.exports.ItemDAO = ItemDAO;

1 个答案:

答案 0 :(得分:0)

正如您在代码中看到的那样:

 this.getRelatedItems = function(callback) {
    "use strict";

    this.db.collection("item").find({})
        .limit(4)
        .toArray(function(err, relatedItems) {
            assert.equal(null, err);
            callback(relatedItems);
        });
};

您需要将集合指定为参数:

this.db.collection("item").