Mongoose嵌套Schema下日志日期无法转换为本地化格式的技术问题
Hey there! Let's fix that date formatting issue you're facing. The problem likely stems from working directly with Mongoose's Document object instead of a plain JavaScript object, which can restrict how you manipulate nested properties like your log array. Here's how to resolve it step by step:
Step 1: Convert Mongoose Document to Plain JS Object
First, when you fetch the user with User.findById, the result is a Mongoose Document instance—not a regular JS object. These documents have special wrappers around nested arrays (like log) that can make direct manipulation tricky. Convert it to a plain object first using toObject():
User.findById(_id, (error, result) => { if(!error){ // Convert Mongoose document to plain JS object const userData = result.toObject(); let responseObject = { ...userData }; // Create a copy to avoid modifying the original document
Step 2: Filter and Limit Logs (Your Existing Logic)
Keep your existing code for filtering by from/to dates and applying the limit parameter—this part works fine once you're dealing with a plain object:
if(query.from || query.to){ let fromDate = new Date(0) let toDate = new Date() if(query.from){ fromDate = new Date(query.from) } if(query.to){ toDate = new Date(query.to) } fromDate = fromDate.getTime() toDate = toDate.getTime() responseObject.log = responseObject.log.filter((session) => { let sessionDate = new Date(session.date).getTime() return sessionDate >= fromDate && sessionDate <= toDate }) } if(query.limit){ responseObject.log = responseObject.log.slice(0, parseInt(query.limit)) // Ensure limit is treated as a number }
Step 3: Convert Dates to Localized Format
Now that you have a plain JS array in responseObject.log, you can iterate over each entry and convert the ISO date string to your desired localized format using toLocaleDateString(). You can even customize the format with options:
// Convert each log entry's date to localized format responseObject.log = responseObject.log.map(session => { // Create a Date object from the stored ISO string const dateObj = new Date(session.date); // Customize the format here—example outputs "December 15, 2015" const localizedDate = dateObj.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); // Return the session with the updated date return { ...session, date: localizedDate }; });
Step 4: Finalize Response Object
Finish up by adding the count property and sending the response (don't forget error handling!):
responseObject.count = result.log.length; // Use original result's log length for total count response.json(responseObject); } else { response.status(400).json({ error: "User not found or invalid request" }); } });
Why This Works
By converting the Mongoose Document to a plain JavaScript object with toObject(), you remove Mongoose's special array wrapper, allowing you to freely iterate over and modify the log entries. The map() method lets you update each session's date property without altering the original data.
Full Modified Code
Here's the complete updated endpoint code for reference:
app.get("/api/users/:_id/logs", (request, response) => { let _id = request.params._id; let query = request.query; User.findById(_id, (error, result) => { if(!error){ const userData = result.toObject(); let responseObject = { ...userData }; if(query.from || query.to){ let fromDate = new Date(0) let toDate = new Date() if(query.from){ fromDate = new Date(query.from) } if(query.to){ toDate = new Date(query.to) } fromDate = fromDate.getTime() toDate = toDate.getTime() responseObject.log = responseObject.log.filter((session) => { let sessionDate = new Date(session.date).getTime() return sessionDate >= fromDate && sessionDate <= toDate }) } if(query.limit){ responseObject.log = responseObject.log.slice(0, parseInt(query.limit)) } // Convert dates to localized format responseObject.log = responseObject.log.map(session => { const dateObj = new Date(session.date); const localizedDate = dateObj.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); return { ...session, date: localizedDate }; }); responseObject.count = result.log.length; response.json(responseObject); } else { response.status(400).json({ error: "Failed to fetch user data" }); } }) });
内容的提问来源于stack exchange,提问作者Imangi

