1. ホーム
  2. node.js

[解決済み] Node.js: req.paramsとreq.bodyの比較

2022-02-28 16:44:19

質問

MEANスタックでnode、express、angular、mongodbを使って基本的なtodoアプリを作るために、いくつかの異なるチュートリアルからコードをこつこつと集めています。あるチュートリアルでは、GET、POST、DELETEアクションのためのAPIを作成することをカバーしていましたが、POSTを無視しました。そこで、私は既存のTodoを更新する関数を書くことに挑戦しました。この関数が動作するようになったとき、req.paramsに関連する理解できないエラーに遭遇しました。

関連するコード

ノードです。

app.js内

app.put('/api/todos/:_id', ngRoutes.update);

につながる。

exports.update = function(req, res){
    var user_id = req.cookies ?
        req.cookies.user_id : undefined;

    Todo.findByIdAndUpdate(req.params._id, 
        { $set: { 
            updated_at : Date.now(), 
            content : req.body.formText
        }}, function (err, todo) {
    if (err) 
        res.send(err)
    Todo.find({ user_id : user_id}, function(err, todos) {
        if (err) res.send(err);
        res.json(todos);
    });
    });
    };

Angularです。

    $scope.update = function(id) {
        $http.put('/api/todos/' + id, this.todo)            
        .success(function(data) {
                    console.log(data);
                    $scope.todos = data;
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
  };

JADE/HTMLです。

form(ng-submit="update(todo._id)")
    input.update-form(ng-show="todo.updating" type="text", name="content", ng-model="todo.formText" placeholder="{{todo.content}}")

この関数は正常に動作します。問題のTodoを更新し、更新された値でページに再読み込みされるようにリスト全体を返します。

しかし、ノードのコード内で

content : req.body.formText

になります。

content : req.params.formText

HTTPレスポンスとして、以下のエラーが表示されます。

Object { 
message: "Cast to string failed for value "undefined" at path "content"", 
name: "CastError", 
type: "string", 
path: "content" }

whileでも、関数の他の場所で。

req.params._id

は、Todo の '_id' プロパティを取得し、それを使ってデータベース内の適切なドキュメントを検索するのに問題なく動作します。さらに、Firefox の開発者ツールでリクエストを表示すると、todo オブジェクトが JSON 形式で "Params" タブの下に表示されます。

なぜこのようなことが起こるのでしょうか?req.paramsとreq.bodyの違いは何ですか?また、なぜ後者はうまくいき、前者はうまくいかないのですか?

解決方法は?

req.params はルートパラメータ用で、フォームデータ用ではありません。

そのルートであなたが持っている唯一のパラメータは _id :

app.put('/api/todos/:_id', ...)

docsから。

req.params
このプロパティは、以下のプロパティにマッピングされたオブジェクトです。 という名前のルートの "parameters "を指定します。たとえば、ルート /user/:nameとすると、"name "プロパティはreq.params.nameとして利用できます。 このオブジェクトのデフォルトは{}です。

のソースになります。 http://expressjs.com/en/4x/api.html#req.params

req.body
リクエストで送信されたデータのキーと値のペアが含まれています。 の本体です。デフォルトでは未定義であり、以下のような場合に設定されます。 body-parserやmulterなどのボディパーシングミドルウェアを使用します。

のソースになります。 http://expressjs.com/en/4x/api.html#req.body