Getting {"message":"Cannot access member '_id' of undefined","name":"TypeError"}

I am trying to use the mongodb trigger for the purpose of sending notification to the user but facing some problem . while Adding trigger , i have added below code in function field.
exports = async function(changeEvent) {
console.log(“changeEvent”);
console.log(JSON.stringify(changeEvent));
// A Database Trigger will always call a function with a changeEvent.
// Documentation on ChangeEvents: https://docs.mongodb.com/manual/reference/change-events/

// This sample function will listen for events and replicate them to a collection in a different Database
// if (!changeEvent.documentKey || !changeEvent.documentKey._id || !changeEvent.ns || !changeEvent.ns.coll) {
// console.log(“Required properties are missing.”);
// return;
// }
console.log(“hello”)
// Access the _id of the changed document:
const docId = changeEvent.documentKey._id.toString();
console.log(“Document ID:”, docId);

// Get the MongoDB service you want to use (see “Linked Data Sources” tab)
// Note: In Atlas Triggers, the service name is defaulted to the cluster name.
const serviceName = “mongodb-atlas”;
const database = “Avkash”;
const collection = context.services.get(serviceName).db(database).collection(changeEvent.ns.coll);
console.log(“Connected to collection:”, changeEvent.ns.coll);
// Get the “FullDocument” present in the Insert/Replace/Update ChangeEvents
try {
// If this is a “delete” event, delete the document in the other collection
if (changeEvent.operationType === “delete”) {
await collection.deleteOne({“_id”: docId});
}

// If this is an "insert" event, insert the document into the other collection
else if (changeEvent.operationType === "insert") {
  await collection.insertOne(changeEvent.fullDocument);
  console.log("Document inserted into collection.");
}

// If this is an "update" or "replace" event, then replace the document in the other collection
else if (changeEvent.operationType === "update" || changeEvent.operationType === "replace") {
  await collection.replaceOne({"_id": docId}, changeEvent.fullDocument);
  console.log("Document replaced in collection.");
}

} catch(err) {
console.log("error performing mongodb write: ", err.message);
}
};


getting below error for above code
{“message”:“Cannot access member ‘_id’ of undefined”,“name”:“TypeError”}
Please help
also below is the data that i have in my database
image

Bit hard to read the code without re-formatting, but one of the places you’re accessing the property “_id” is from an object that is not set, so if you have:

var myID = myDocument._id

and myDocument is not set to anything then you’ll get that error.

I’d suggest you step through where you are accessing data like this and debug which variable is not set, looks like it’s here:

const docId = changeEvent.documentKey._id.toString();

If you’re not sure what properties are available then output a JSON.Stringify of the object to the console.

Take a look at the documentation of event data on change events:

Sorry for the inconvenience happened for reading code .
i have doubt that this code given by mongo itself , I want trigger should get called on insert , update, replace . for which they have alredy given the code then do i need make any changes in that code or i can use that as it is ?

here is the clean code :
exports = async function(changeEvent) {
const docId = changeEvent.documentKey._id;
const serviceName = “mongodb-atlas”;
const database = “Avkash”;
const collection =
context.services.get(serviceName).db(database).collection(changeEvent.ns.coll);
try {

if (changeEvent.operationType === "delete") {
  await collection.deleteOne({"_id": docId});
}


else if (changeEvent.operationType === "insert") {
  await collection.insertOne(changeEvent.fullDocument);
}


else if (changeEvent.operationType === "update" || changeEvent.operationType === "replace") {
  await collection.replaceOne({"_id": docId}, changeEvent.fullDocument);
}

} catch(err) {
console.log("error performing mongodb write: ", err.message);
}
};

Setting up a test trigger / function with default settings I get the same error when running the trigger in debug mode through the function editor as the variable passed to the function is not a real change object.

Inserting an actual document runs the code as expected, obviously you get some errors if you’re re-inserting the same document as the sample code does.

Adding in a console.log to show what’s going on:

I get this in the log when inserting a document to the collection:

Running through the function editor I get this error, which is expected:

Modifying the code so the insert will insert a copy of the document (by removing the _id field so that we don’t get a duplicate key error):

    // If this is an "insert" event, insert the document into the other collection
    else if (changeEvent.operationType === "insert") {
      var newDoc = changeEvent.fullDocument;
      delete newDoc._id
      await collection.insertOne(newDoc);
    }

This is when I checked the collection and realised the trigger triggered the trigger! Lots of documents were created. To avoid this you could create a property to check if the data source of a document was the trigger or a manual insert etc, or just insert into a different collection.

Your use-case was to notify the user, so you’ll need to filter out the data you want to track, either with settings on the trigger (onInsert / onDelete etc) you could also setup a pipeline to filter or put logic in the trigger function.
As to how the user is notified, you’d need to either write to another collection or use the trigger to call another API to send the notification to the user somehow.

So the default code provided in a trigger function should work, but you’ll need to tailor it to your needs.