Help with :UpdateAsync()

Hello,
I have always used SetAsync() for saving data, until I saw this post.
I’m making my next game, and I want to use UpdateAsync(), so, following the tutorial linked above, I wrote the following code:

local function saveData(player,stat)
	
	local startTime = tick()

	warn('Loading '..player.Name..'\'s data...')

	local success,errorMessage
	local statStore
	local attempts = 0
	
	local playersData = stat.Value
	
	while not success do
		
		success,errorMessage = pcall(function()
			dataStore:UpdateAsync(player.UserId..'-'..stat.Name,function(oldValue)
				local previousData = oldValue or {DataId = 0}
				if playersData.DataId == previousData.DataId then
					playersData.DataId = playersData.DataId + 1
					return playersData
				else
					return nil
				end
			end)
			
			
		end)
		
		attempts += 1

		if attempts >= 10 then
			break
		end

		if not success then
			warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
		end
		
		
	end
	
	if success then
		local endTime = tick()

		warn('Successfully saved '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')

	end
end

I get the following error:

Help is appreciated!
:slightly_smiling_face:

The error means that you are indexing (indexing mean like game.Workspace, you index Workspace) a number.

Make sure the oldData is a table and not any other datatype.

stat.Value is just an intValue, I know what indexing is, I don’t know why it’s happening though.

What do you mean

I know what a table is, but the old table is passed as a parameter.

Here is the full script if it helps:

local dataStoreService = game:GetService('DataStoreService')
local dataStore = dataStoreService:GetDataStore('Data')
local players = game:GetService('Players')

local function loadData(player,stat)
	
	local startTime = tick()
	
	warn('Loading '..player.Name..'\'s data...')
	
	local success,errorMessage
	local statStore
	local attempts = 0
	
	
	while not success do
		
		success,errorMessage = pcall(function()
			statStore = dataStore:GetAsync(player.UserId..'-'..stat.Name)
		end)
		
		attempts += 1
		
		if attempts >= 10 then
			break
		end
		
		if not success then
			warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
		end
		
		
	end
	
	if success then
		local endTime = tick()
		
		warn('Successfully loaded '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')
		
		
		if statStore ~= nil then
			player.leaderstats[stat.Name].Value = statStore
		end
	end
	

	
	
end

local function saveData(player,stat)
	
	local startTime = tick()

	warn('Loading '..player.Name..'\'s data...')

	local success,errorMessage
	local statStore
	local attempts = 0
	
	local playersData = stat.Value
	
	while not success do
		
		success,errorMessage = pcall(function()
			dataStore:UpdateAsync(player.UserId..'-'..stat.Name,function(oldValue)
				local previousData = oldValue or {DataId = 0}
				if playersData.DataId == previousData.DataId then
					playersData.DataId = playersData.DataId + 1
					return playersData
				else
					return nil
				end
			end)
			
			
		end)
		
		attempts += 1

		if attempts >= 10 then
			break
		end

		if not success then
			warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
		end
		
		
	end
	
	if success then
		local endTime = tick()

		warn('Successfully saved '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')

	end
end

players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new('Folder',player)
	leaderstats.Name = 'leaderstats'
	
	local wins = Instance.new('IntValue',leaderstats)
	wins.Name = 'Wins'
	
	local rounds = Instance.new('IntValue',leaderstats)
	rounds.Name = 'Rounds'
	
	local deaths = Instance.new('IntValue',leaderstats)
	deaths.Name = 'Deaths'
	
	wait()
	
	for _, stat in pairs(leaderstats:GetChildren()) do
		loadData(player,stat)
	end
end)

players.PlayerRemoving:Connect(function(player)
	for _, stat in pairs(player.leaderstats:GetChildren()) do
		saveData(player,stat)
	end
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		for _, stat in pairs(player.leaderstats:GetChildren()) do
			saveData(player,stat)
		end
	end
	
	wait(2)
end)

Did you meant to use if playersData[DataId] == previousData[DataId] then? Even if you didn’t, try using this code.

What do I define “DataId” as?


That’s the issue. DataID is not even a thing. You’ve randomly addressed it, might wanna use something else.

1 Like

local playersData = stat.Value

Make sure stat.Value is a table that has a key named “DataValue”.

It seems like stat.Value is a number and it is not a table containing player data.
Indexing a number will raise an exception.

1 Like

I’m confused. I’ve never used UpdateAsync before, so I’m unfamilar with it. How would I get PlayerData?

playerData should refer to a properly formatted data that you want to store in the datastore when you are saving with UpdateAsync.

So given how you are using it, it should be a table with the key DataId. It should contain all the info that you want to save for a player. If you’re only saving one thing, e.g. DataId and that is what the stat.Value represents then you should say: local playersData = {DataId = stat.Value}.