Logic error loading and saving datastore values

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    My datastore is not functioning correctly.

  2. What is the issue? Include screenshots / videos if possible!
    I am learning how to use datastores, however the code below does not function as intended. There are no errors or anything in the output (apart from the “data successfully loaded / saved”), and I can’t get to the bottom of the issue.

-- Define variables
local DatastoreService = game:GetService("DataStoreService")
local DonatedStore = DatastoreService:GetDataStore("Donated")

-- Fires when player joins
game:GetService("Players").PlayerAdded:Connect(function(player)
	-- Define leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	local donated = Instance.new("IntValue")
	donated.Name = "Donated"
	donated.Parent = leaderstats
	
	leaderstats.Parent = player
	
	-- Set donated variable
	local DonatedData = DonatedStore:GetAsync(player.UserId)
	
	-- Check if first time joining
	if DonatedData == nil then
		DonatedData = 0
	end
	
	-- Attempt to load data
	local success, errormessage = pcall(function()
		donated.Value = DonatedData
	end)
	
	-- Check for error
	if success then
		print(player.Name .. "'s data was successfully loaded!")
	else
		warn(errormessage)
	end
end)

-- Fires when player leaves
game:GetService("Players").PlayerRemoving:Connect(function(player)
	-- Saves data
	local success, errormessage = pcall(function()
		DonatedStore:SetAsync(player.UserId, player.leaderstats.Donated.Value)
	end)
	
	-- Check for error
	if success then
		print(player.Name .. "'s data was successfully saved!")
	else
		warn(errormessage)
	end
end)

Nevermind, you just edited your post…

Wait, I saw you speak about a bind to close procedure, but couldn’t read it in time. What does this do?

BindToClose binds the given subprogram to run when the server shuts down. This means you can ensure all data has time to save (the request has time to be executed from the DataStore queue).

local runService = game:GetService("RunService")
local players = game:GetService("Players")

game:BindToClose(function()
    if runService:IsStudio() or #players:GetPlayers() <= 1 then
        task.wait(5)
        return nil
    end

    for _, player in ipairs(players:GetPlayers()) do
        --save data
    end

    task.wait(5)
end)

Here’s the documentation:
DataModel:BindToClose | Documentation - Roblox Creator Hub

Also, GetAsync needs a pcall.

Another question, why is it required to use:

runService:IsStudio() or #players:GetPlayers() <= 1

?

By the way, the code does not work

Can you send the new code? The reason that line is updated is to help prevent spam requests to the store with the same key, which might end up saving outdated data.

-- Define variables
local DatastoreService = game:GetService("DataStoreService")
local DonatedStore = DatastoreService:GetDataStore("Donated")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

-- Fires when player joins
game:GetService("Players").PlayerAdded:Connect(function(player)
	-- Define leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	local donated = Instance.new("IntValue")
	donated.Name = "Donated"
	donated.Parent = leaderstats
	
	leaderstats.Parent = player
	
	-- Set donated variable
	local DonatedData = DonatedStore:GetAsync(player.UserId)
	
	-- Check if first time joining
	if DonatedData == nil then
		DonatedData = 0
	end
	
	-- Attempt to load data
	local success, errormessage = pcall(function()
		donated.Value = DonatedData
	end)
	
	-- Check for error
	if success then
		print(player.Name .. "'s data was successfully loaded!")
	else
		warn(errormessage)
	end
end)

-- Fires when player leaves
game:GetService("Players").PlayerRemoving:Connect(function(player)
	-- Saves data
	local success, errormessage = pcall(function()
		DonatedStore:SetAsync(player.UserId, player.leaderstats.Donated.Value)
	end)
	
	-- Check for error
	if success then
		print(player.Name .. "'s data was successfully saved!")
	else
		warn(errormessage)
	end
end)

local runService = game:GetService("RunService")
local players = game:GetService("Players")

game:BindToClose(function()
	if RunService:IsStudio() or Players:GetPlayers() <= 1 then
		return
	end

	for i, player in Players:GetPlayers() do
		local success, errormessage = pcall(function()
			DonatedStore:SetAsync(player.UserId, player.leaderstats.Donated.Value)
		end)
		
		-- Check for error
		if success then
			print(player.Name .. "'s data was successfully saved!")
		else
			warn(errormessage)
		end
	end
end)

If u learning data store then here.

Hi, this doesn’t really help. There are no errors with my code, it always prints that the data was successfully loaded and saved, but it doesn’t actually do that.