在MEAN app中获取PUT请求的错误

时间:2017-04-12 03:11:39

标签: node.js mongodb angular express mean-stack

我正在尝试在本地安装MongoDB的MEAN堆栈中构建一个todos应用程序。我在PUT请求中收到以下错误。任何帮助将不胜感激。

Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
    at new ObjectID (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/bson/lib/bson/objectid.js:50:11)
    at Function.ObjectID (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/bson/lib/bson/objectid.js:31:42)
    at router.delete.db.todos.update._id (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/routes/todos.js:59:26)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at /mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:281:22
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:354:14)
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:365:14)
ReferenceError: updObj is not defined
    at module.exports (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/routes/todos.js:73:8)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at /mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:281:22
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:354:14)
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:410:3)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:275:10)
ReferenceError: updObj is not defined
    at module.exports (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/routes/todos.js:73:8)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at /mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:281:22
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:354:14)
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:410:3)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:275:10)
ReferenceError: updObj is not defined
    at module.exports (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/routes/todos.js:73:8)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at /mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:281:22
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:354:14)
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:410:3)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:275:10)
ReferenceError: updObj is not defined
    at module.exports (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/routes/todos.js:73:8)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/layer.js:95:5)
    at /mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:281:22
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:354:14)
    at param (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:410:3)
    at next (/mnt/c/JAVADEV/projects/Servers/NodeJsV4.5Server/webapps/ToDo/node_modules/express/lib/router/index.js:275:10)

todos.js(服务器端)

var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('mongodb://user1:user@localhost/meantodo', ['todos']);

router.get('/todos', function (req, res, next) {
    db.todos.find(function (err, todos) {
        if (err) {
            res.send(err);
        } else {
            res.json(todos);
        }
    });
});

router.get('/todo/:id', function (req, res, next) {
    db.todos.findOne({ _id: mongojs.ObjectId(req.params.id) }, function (err, todo) {
        if (err) {
            res.send(err);
        } else {
            res.json(todo);
        }
    });
});

router.post('/todo', function (req, res, next) {
    var todo = req.body;
    if (!todo.text || !(todo.isCompleted + '')) {
        res.status(400);
        res.json({ "error": "Invalid Data" });
    } else {
        db.todos.save(todo, function (err, result) {
            if (err) {
                res.send(err);
            } else {
                res.json(result);
            }
        });
    }
});

router.put('/todo/:id', function (req, res, next) {
    var todo = req.body;
    var updObj = {};

    if (todo.isCompleted) {
        updObj.isCompleted = todo.isCompleted;
    }

    if (updObj.text) {
        updObj.text = todo.text;
    }

    if (!updObj) {
        res.status(400);
        res.json({ "error": "Invalid Data" 
    });
    } else {
        db.todos.update({
            _id: mongojs.ObjectId(req.params.id)
        }, updObj, {}, function (err, result) {
            if (err) {
                res.send(err);
            } else {
                res.json(result);
            }
        });
    }
});

router.delete('/todo/:id', function (req, res, next) {
    db.todos.update({
        _id: mongojs.ObjectId(req.params.id)
    }, updObj, {}, function (err, result) {
        if (err) {
            res.send(err);
        } else {
            res.json(result);
        }
    });
});

module.exports = router;

todos.component.html

<div class="add-todo-form text-center">
    <h1>Add Todo</h1>
    <div class="form-group">
        <input class="form-control input-lg" placeholder="Add Todo..." autofocus #todoText>
        <br>
        <button (click)="addTodo($event, todoText)" class="btn btn-primary btn-block">Create</button>
    </div>
</div>

<div class="todo-list">
    <div *ngFor="let todo of todos">
        <div class="col-md-1">
            <input type="checkbox" [checked]="todo.isCompleted" (click)="updateStatus(todo)">
        </div>
        <div class="col-md-7">
           <span [class.hidden]="todo.isEditMode">{{todo.text}}</span>
           <input type="text" [class.hidden]="!todo.isEditMode" [value]="todo.text" (keypress)="updateTodo">
           <input type="button" [class.hidden]="!todo.isEditMode" value="Cancel" (click)="setEditState(todo)">
        </div>
        <div class="col-md-4 btns">
            <input (click)="deleteTodo(todo)" type="button" class="btn btn-danger pull-right" value="Delete">
            <input [class.disabled]="todo.isCompleted" (click)="setEditState(todo, true)" type="button" class="btn btn-default pull-right" value="Edit">
        </div>
    </div>
</div>

todos.component.ts

import { Component, OnInit } from '@angular/core';
import { TodoService } from '../services/todo.service';
import {Todo} from '../Todo';

@Component({
    moduleId: module.id,
    selector: 'todos',
    templateUrl: 'todos.component.html',
})

export class TodosComponent implements OnInit {
    todos: Todo[];

    constructor(private _todoService: TodoService){

    }

    ngOnInit(){
        this.todos = [];
        this._todoService.getTodos()
        .subscribe(todos => {
            this.todos = todos;
        });
    }

    addTodo(event, todoText){
        var result;
        var newTodo = {
            text: todoText.value,
            isCompleted: false
        };

     result = this._todoService.saveTodo(newTodo);
     result.subscribe(x => {
         this.todos.push(newTodo);
         todoText.value = '';
     });
    }

    setEditState(todo, state){
        if(state){
            todo.isEditMode = state;
        } else {
            delete todo.isEditMode;
        }
    }

    updateStatus(todo){
        var _todo = {
            _id: todo._id,
            text: todo.text,
            isCompleted: !todo.isCompleted
        };

        this._todoService.updateTodo(_todo)
        .subscribe(data => {
            todo.isCompleted = !todo.isCompleted;
        });
    }

    updateTodoText(event, todo){
        if(event.which === 13){
            todo.text = event.target.value;
            var _todo = {
            _id: todo._id,
            text: todo.text,
            isCompleted: todo.isCompleted
        };

        this._todoService.updateTodo(_todo)
        .subscribe(data => {
            this.setEditState(todo, false);
        })
        }
    }

    deleteTodo(todo){
        var todos = this.todos;

        this._todoService.deleteTodo(todo._id)
        .subscribe(data => {
            if(data.n == 1){
                for(var i = 0; i < todos.length; i++){
                    if(todos[i]._id == todo._id){
                        todos.splice(i, 1);
                    }
                }
            }
        })
    }
}

todo.service.ts

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class TodoService {
    constructor(private _http: Http) {
    }

    getTodos() {
        return this._http.get('/api/todos')
            .map(res => res.json());
    }

    saveTodo(todo){
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this._http.post('/api/todo', JSON.stringify(todo), {headers: headers})
               .map(res => res.json());
    }

    updateTodo(todo){
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this._http.put('/api/todo/'+todo._id, JSON.stringify(todo), {headers: headers})
               .map(res => res.json());
    }

    deleteTodo(id){
        return this._http.delete('/api/todo/'+id)
           .map(res => res.json());
    }
}

2 个答案:

答案 0 :(得分:0)

传递给ObjectId函数的值不是有效格式。

 _id: mongojs.ObjectId(req.params.id)

id应该格式化为'58eda0909b079aff3acb9b67'。您可能需要console.log(req.params.id)来验证值是否正确到达api。

答案 1 :(得分:0)

在todos.js中,您是否准备了一个中间件(例如router.use(bodyParser.json());this link)将请求对象解析为req.body?