Start a new topic
Answered

PostDelete: No access to deleted record

Hello


Either I'm doing something completely wrong or ist just not working (anymore). I added a PostDelete Hook on a collection. When a delete operation happens the code will be execute, that works. I then try to get information from the deleted record:

function onPostDelete(request, response, modules) {
  var logger = modules.logger;
  response.body = modules.utils.tempObjectStore.get('recordsDeleted');

  logger.info(response.body);
    response.complete(200);
}

 The output in the console is:

undefined 


The "undefined" comes from the response.body (base example from documentation here). 


Luckily I could switch to the preDelete Hook where it works (by other example in your documentation). I just wanted to know you and any other developers.


Regards



Best Answer

Hi Tayger,


Thanks for adding additional information.


1) The utils.tempObjectStore is key-value store for persisting temporary data between a pre- and post-hook. Therefore, you can call utils.tempObjectStore.set(key, value) in a pre-hook and then call utils.tempObjectStore.get(key) in the post-hook to get the passed value from the pre-hook. See example here - https://devcenter.kinvey.com/rest/reference/business-logic/reference.html#tempObjectStore


Since you are not setting a key "recordsDeleted" and a value in the onPreDelete hook, you are getting undefined in the onPostDelete hook as there is no such key-value pair.


2) Regarding onPreDelete hook firing even if there is no record to delete - please see the processing flow of a Kinvey request - https://devcenter.kinvey.com/rest/tutorials/look-behind-the-scene#processing-flow.

The onPreDelete hook is being fired before the request goes to the database - therefore at the time of execution of the onPreDelete hook, the function does not know if there is such a record or not in the database. The pre-hook is useful when you want to alter the request body or check request parameters (for example check who is executing the request and cancel if needed) before the request goes for execution in the database.


I hope the above has helped.


Regards

Martin Apostolov


Hi Tayger,

Can you share the onPreDelete function where you are setting the recordsDeleted value?


Regards

Martin Apostolov

Hi Martin


Sure! I anyway wanted to share some further infos...


I'm not sure what you mean by "" but I assume this happens in the background (logical delete, not physical delete).


I don't know in what part you're interested in. Here's my preDelete code (repeating code removed): 

function onPreDelete(request, response, modules) {
  // var logger = modules.logger;
  var parameter = JSON.parse(request.params.query);
  var gameId = parameter['game.id']; 
  var listId = '';
  var list;
  
  // SPOTS: Remove all physical spot entries of deleted game
  modules.collectionAccess.collection("spots").remove({"game.id": gameId}, function(err, count) {});

  // FILES: Delete all game related files 
  var appKey = modules.backendContext.getAppKey();
  var masterSecret = modules.backendContext.getMasterSecret();
  var authString = "Basic " + modules.utils.base64.encode(appKey + ":" + masterSecret);
  
  modules.request.request(
    {uri: 'https://baas.kinvey.com/appdata/kid_xxxxxxxx/_blob/?query={"gameid":"'+gameId+'"}',
     method:'DELETE',
     headers: {"Authorization": authString}
     // Works not for file delete if not owner (unlcear how to give overall file delete permission to request.headers.authorization)
     // headers: {"Authorization": request.headers.authorization}
    },
    function(error, res, body){});
  
  /* Works as well
  var appKey = modules.backendContext.getAppKey();
  var masterSecret = modules.backendContext.getMasterSecret();
  var authString = "Basic " + modules.utils.base64.encode(appKey + ":" + masterSecret);

  modules.request.del(
    {uri: 'https://baas.kinvey.com/appdata/kid_xxxxxxxx/_blob/?query={"gameid":"'+gameId+'"}',
     method:'DELETE',
     //params: {'gameid':gameId}, // error: handover by URI
     headers: {"Authorization":authString}
    },
    function(error, res, body){});
    */
  
  response.continue();
}

JSON.parse(request.params.query) : "JSON.parse" is important otherwise it's treated as text and therefore not readable.


The preEvent code will be executed even if the record(s) (to be deleted) does not exist. Example: You have a collection named "myCollection" with a preEvent Hook on it. Now you delete a record in myCollection with _id = 1234 BUT there is not record with that _id. The preEvent will still fire! 

Well, that's a philosophic question: This behaviour helps to find out who/when a delete takes place (with or without success). On the other hand: Is it valid/wanted to execute the preEvent Hook if there is no associated record(s) to be deleted?


Regards

Answer

Hi Tayger,


Thanks for adding additional information.


1) The utils.tempObjectStore is key-value store for persisting temporary data between a pre- and post-hook. Therefore, you can call utils.tempObjectStore.set(key, value) in a pre-hook and then call utils.tempObjectStore.get(key) in the post-hook to get the passed value from the pre-hook. See example here - https://devcenter.kinvey.com/rest/reference/business-logic/reference.html#tempObjectStore


Since you are not setting a key "recordsDeleted" and a value in the onPreDelete hook, you are getting undefined in the onPostDelete hook as there is no such key-value pair.


2) Regarding onPreDelete hook firing even if there is no record to delete - please see the processing flow of a Kinvey request - https://devcenter.kinvey.com/rest/tutorials/look-behind-the-scene#processing-flow.

The onPreDelete hook is being fired before the request goes to the database - therefore at the time of execution of the onPreDelete hook, the function does not know if there is such a record or not in the database. The pre-hook is useful when you want to alter the request body or check request parameters (for example check who is executing the request and cancel if needed) before the request goes for execution in the database.


I hope the above has helped.


Regards

Martin Apostolov

Hi Martin

Thanks a ton for the information/links! Yes, that helped! I was not aware I have to store values in preDelete hook in order to catch them in postDelete hook. 


I also agree that the preDelete doesn't have to know and doesn't have to care if data to be deleted do exist or not. That way it should fire in every case.


Regards and thanks!

Login or Signup to post a comment