I have a block of code that is re-used and I want to use functional programming to remove this duplication.
My code takes an array of items, splits the items into batches of 500 and then does some kind of work on them.
In the first function it deletes items from a database:
Delete function:
const deleteDocuments = async (documentReferences) => {
const batchesOf500 = Math.ceil(documentReferences.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = getBatchWriter();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
if(index < documentReferences.length) {
const documentPath = documentReferences[index];
batch.delete(documentPath);
}
}
await batch.commit();
}
}
The second function is almost identical but instead of deleting from a database, it writes to the database:
Add function:
const writeToCollection = async (dataArray, collectionRef) => {
const batchesOf500 = Math.ceil(dataArray.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = getBatchWriter();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
if(index < dataArray.length) {
const [key, value] = dataArray[index];
const doc = getDocFromPath(key);
batch.set(doc, value);
}
}
}
await batch.commit();
}
}
These functions are almost identical, so I have write a higher order function to do most of the leg-work.
Higher order function:
const runFunctionInBatchesOf500 = (func, dataArray) => {
const batchesOf500 = Math.ceil(dataArray.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = this.firestore.batch();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
const document = dataArray[index];
func(document, batch);
}
}
await batch.commit();
}
And to it you can create your own functionality to apply to each document and use it like this:
const write = (document, batch) => {
const doc = getDocFromPath(key);
batch.set(doc, value);
};
await runFunctionInBatchesOf500(write, dataArray);
This all works but I think I am missing something. Is this an efficient use of higher order functions? What would a more elegant, FP-style solution be?
key
comes from but changing the code would invalidate that answer. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see What should I do when someone answers my question? as well as what you may and may not do after receiving answers. \$\endgroup\$key
value back in but to what end? Other users will notice it and either mention it or be confused when my request is regarding functional programming. \$\endgroup\$