How to add values to datastores

my mind been stuck at this lately, so if i made a simple datastore for leaderstats like this:

local datastoreservice = game:GetService("DataStoreService")

local MoneyDataStore = datastoreservice:GetDataStore("MoneyData")

local players = game.Players

players.PlayerAdded:Connect(function(plr)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("NumberValue")
	Cash.Parent = leaderstats
	Cash.Name = "Cash"

	local Bank = Instance.new("NumberValue")
	Bank.Parent = leaderstats
	Bank.Name = "Bank"

	local sucess, data, att = nil, nil, 1

	repeat
		sucess, data = pcall(function()
			return MoneyDataStore:GetAsync(plr.UserId)
		end)

		if not sucess then
			warn("Cannot load data for", plr.Name)
			task.wait(3)
		end
		att += 1
	until sucess or att == 5

	if sucess then
		
		if data then

			Cash.Value = data["Cash"]
			Bank.Value = data["Bank"]
			
		end
	else
		warn("Cannot load data")
		--plr:Kick("Cannot load your data, please retry later")
	end

end)

local function saveData(plr)
	
	local success, err, att = nil, nil, 1

	local data = {}

	repeat
		success, err = pcall(function()
			data = {
				["Bank"] = plr.leaderstats.Bank.Value;
				["Cash"] = plr.leaderstats.Cash.Value;
			}
  
			MoneyDataStore:SetAsync(plr.UserId, data)
		end)

		if not success then
			warn(err)
			task.wait(3)
		end
		att += 1
	until success or att == 5

	if success then
		
	else

		warn(err)
	end
end

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	task.wait(2)
	for _, player in game.Players:GetPlayers() do
		task.spawn(function()
			saveData(player)
		end)
	end
end)

then i publish the game and people start playing it and asked i add a value named “Wins” the most sensable thing to do is just add a value like this:

	local Wins= Instance.new("NumberValue")
	Wins.Parent = leaderstats
	Wins.Name = "Wins"

but the issue is when i load the data, whats gonna essentially happen is that the data will load in as

[“Cash”] = 100, [“Bank”] = 200

and the issue here is if i load the data as

Wins.Value = data[“Wins”]

it would be nil because there isnt any index under the name “Wins” which then make the value nil, and not 0.

what i thought would be the solution is to check if the value is nil, and if it is then just set it as 0, but what if i have a lot of things in the leaderstats?

what would happen is that i would need to check for every single number value or bool value etc if its nil or not which will not be optimized nor will it be effective because why would you need to check if its nil if the player has it.

so whats the best way to fix it?

any help will be appreciated

the data is a dictionary so you can loop through each key value pair and assign the value

if the data doesnt have Wins, but there is a Wins value, then it will just do nothing to the Wins value

for key, value in pairs(data) do
  local valueObject = leaderstats:FindFirstChild(key)
  valueObject.Value = value
end
1 Like

This will still throw an error, as FindFirstChild just returns nil if it isn’t found.

Instead @TypicalCEO could do something like:

if not data.Wins then
    data.Wins = 0
end

before setting any data. Just iterate with a general data.

this is what i was thinking to do but if theres a lot of values that have the possibility to be nil, then it wont be very optimized to check for every single one,

i will try that thank you

char limit

Compare against default stats maybe. For instance:

local defaultData = {
    ["Cash"] = 0,
    ["Money"] = 0,
    ["Wins"] = 0
}

--then
for key, value in next, defaultData, nil do
    if not data[key] then
        data[key] = value
    end
end

If you are going to use @happya_x 's solution make sure to check whether the instance is nil!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.