I have a callback function :AfterSave from DataStore2 (API - DataStore2) that returns Enum.ProductPurchaseDecision.PurchaseGranted as part of a developer product handling script.
The problem is that the callback is called each time the data is autosaved even after the purchase has been already granted. Is there a way to stop this?
I don’t think there are errors or what do you mean. It works as expected (it’s called each time data is saved/autosaved), but I don’t want it to be called anymore after being called once.
local function incrementData(player, productType, value)
local data = DataStore2(productType, player)
if data:IsBackup() then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
data:Increment(value)
local result
data:AfterSave(function()
result = Enum.ProductPurchaseDecision.PurchaseGranted
end)
while result == nil do
RunService.Heartbeat:Wait()
end
return result
end
I want that callback to be called only once, grant the product, and then no longer listen to it.
I’ve not used DataStore2 before so I am unsure of whether the method you are using is a good way to do this. The anonymous callback called during data:AfterSave is permanently hooked and so will always be called however the save takes place. Maybe you could tag the value as saved using a dictionary where value = true and save that rather than just the value, then you can check for the value being true before returning the Enum. Or use a connect/disconnect method that connects initially to data:AfterSave then after the first call you disconnect and it will no longer be called.
You can edit the source code a tiny bit to suit your needs.
function DataStore:AfterSave(callback)
table.insert(self.afterSave, callback)
end
Change the above to:
function DataStore:AfterSave(callback: () -> boolean): number
local nextIndex = #self.afterSave + 1
if self.afterSave[nextIndex] then
warn(`Overwriting a callback at index {nextIndex}`)
end
self.afterSave[nextIndex] = callback
return nextIndex
end
And then just do this in your code:
local assignedIndex = data:AfterSave(function()
result = Enum.ProductPurchaseDecision.PurchaseGranted
data.afterSave[assignedIndex] = nil
end)
Oh also, in the following code, make sure you change the ipairs to pairs or just do generalized iteration.
for _, afterSave in ipairs(self.afterSave) do --Change to pairs(self.afterSave) or just self.afterSave
local success, err = pcall(afterSave, save, self)
if not success then
warn("Error on AfterSave:", err)
end
end