ここで複数の電話をかけることは、実際には必要なく、効率的な場所にはありません。複数の呼び出しを行う代わりに、選択したオプションに従ってクエリを作成して更新します。
各プロパティを変更するためのさまざまな方法を構築することも完全に不要です。正しく表現されていれば、標準的なマングース(実際には実際にはMongoDB)メソッドは、意図された関数を十分に記述する必要があります。それ以外の場合は行うことは面倒で、非現実的であり、代わりに特定のプロパティ呼び出しの建物のクエリオプションを使用すると、通常行うには何を意味するかです:
router.post('/changeinformation',
passport.authenticate('jwt', {session: false}), (req, res) => {
let query = { },
update = { $set: { } };
if (req.body.changeEmail) {
query['email'] = req.body.currentEmail; // presuming this is current
update.$set['email'] = req.body.email;
}
if (req.body.changeUsername) {
query['name'] = req.body.currentName;
update.$set['name'] = req.body.name;
}
// One call only
User.update(query,update,(err,result) => {
if (err) {
if (err.code === 11000) { // Duplicate key error
res.json({ success: false, msg: 'email or name already exists' });
} else {
res.json({ success: false, msg: err.message });
}
} else {
if (result.n === 0) {
res.json({ success: false, msg: 'Requested details not found' });
} else {
res.json({ success: true, msg: 'Details updated successfully' });
}
}
});
});
をので、代わりに分岐して別の呼び出しを行うの、あなたは、単に提供するオプションを検査し、構築しますそこからクエリと更新ステートメント。これらは、通常のオブジェクト表現だけでは「設計による」ものであり、オブジェクトのように構造を操作するだけのものです。
ここで最初に主な出発点は、変更のための「目標値の有無の確認」のクエリの使用です。それは本当に非効率です。あなたが本当に求めているのは、コレクション内の他のオブジェクトが同じname
またはemail
を共有できないように、これらの値が代わりに「ユニーク」であることです。あなたはこれを強制方法は、「インデックス」を使用することです:
const userSchema = new Schema({
...
email: { type: String, required: true, unique: true },
name: { type: String, required: true, unique: true }
...
});
スキーマ内のもの"unique"
プロパティは、「ユニーク」でそのプロパティにインデックスを作成するためにマングースを教えてください。コレクションに同じ値の複数の値を追加しようとすると(つまり、既存のエントリと同じ値にユーザー名を変更すると)、これは「重複キーエラー」をスローします。これはエラーコードとそれに応じて対応します。
if (err.code === 11000) {
res.json({ success: false, msg: 'email or name already exists' });
} else {
res.json({ success: false, msg: err.message });
}
多くの直接的作るよります:
は、だからそれはコードがエラーコードが返されたテストし、それが重複キーエラーであると同定された際に応答して、適切なメッセージを与えることによって、何をするかですターゲット値がすでに存在するかどうかをテストするために別のクエリを使用します。また、現在のコードの "クエリ"とそれに続く "更新"の間に、他の何かが実際にデータを変更できる可能性があるので、はるかに信頼性が高いです。ユニークなインデックスを実施せずにエラーをチェックすることなく、重複を作成するリスクがあります。正しい職場に適したツールを使用してください。
ここでのもう1つのチェックは、何かがアップデートによってまったくマッチしたかどうかを確認することです。これは、n
プロパティの下にある.update()
の応答オブジェクトに常に含まれています。これは、条件が実際に一致したドキュメントの数を示します。
メッセージ自体については、「そのまま」としておくことができます。個人的には完全に妥当であることがわかります。または、文の構成と同様に、要求パラメータに同様の分岐ロジックを使用して、戻る。一例として、
:
let errStr = (req.body.changeEmail && req.body.changeUsername)
? "email or name"
: (req.body.changeEmail) ? "email" : "name";
res.json({ success: false, msg: `${errStr} already exists` });
そして、うまくいけば、あなたは一般的なアイデアを得ます。
しかし、実際には必要ないときに、さまざまな呼び出しを連鎖して複数の要求を行うことよりもずっと優れています。追記として
、我々は実際にはより現代的な持っていると、コールバックのネストを使用するよりも、物事に対処する方法をお勧めします。約束事はしばらくありましたが、実際にはnodejs v8.xxリリースのように、実際にはasync
/await
構文をサポートする環境で作業する必要があり、実際にはLTS(Long Term Support)バージョン:
router.post('/changeinformation',
passport.authenticate('jwt', {session: false}), async (req, res) => {
let query = { },
update = { $set: { } };
if (req.body.changeEmail) {
query['email'] = req.body.currentEmail; // presuming this is current
update.$set['email'] = req.body.email;
}
if (req.body.changeUsername) {
query['name'] = req.body.currentName;
update.$set['name'] = req.body.name;
}
try {
let result = await User.update(query,update);
if (result.n === 0) {
let msgStr = (req.body.changeEmail && req.body.changeUsername)
? "email or name"
: (req.body.changeEmail) ? "email" : "name";
res.json({ success: false, msg: `Requested ${msgStr} not found` });
} else {
res.json({ success: true, msg: 'Details updated successfully' });
}
} catch(e) {
if (e.code === 11000) {
let errStr = (req.body.changeEmail && req.body.changeUsername)
? "email or name"
: (req.body.changeEmail) ? "email" : "name";
res.json({ success: false, msg: `${errStr} already exists` });
} else {
res.json({ success: false, msg: e.message });
}
}
});
実際には、解決する非同期関数のチェーンがあり、このインスタンスでは実際に避けようとしているものがあります。しかし、ブロックtry..catch
を含む一般的なケースでも、少なくとも論理的な流れがあり、コードの可読性が向上します。
これは私が探していたものです。私はそれがやっているやり方に根本的に何か間違っていることを知っていました。ありがとうございました –