Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to properly use UpdateAsync?

I've been trying use UpdateAsync to save data in my game when you leave and this is what I came up with:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local StoredLevel = DataStoreService:GetDataStore("Level")
local StoredExp = DataStoreService:GetDataStore("Exp")
local StoredMaxExp = DataStoreService:GetDataStore("MaxExp")

Players.PlayerRemoving:Connect(function(player)
	
	local success, errormessage = pcall(function()
		StoredLevel:UpdateAsync(player.UserId.."-Level", player.Stats.Level.Value)
		StoredExp:UpdateAsync(player.UserId.."-Exp", player.Stats.Exp.Value)
		StoredMaxExp:UpdateAsync(player.UserId.."-MaxExp", player.Stats.MaxExp.Value)
	end)
	
	if success then
		print("Player Data Successfully Saved!")
	else
		warn("Error:"..errormessage)
	end
	
end)

but instead of saving, I get this message:

16:38:53.316 - Error:Unable to cast value to function

1 answer

✓ Accepted answer

UpdateAsync (<Psst. That's a link!) works by calling a function to update the key you provide.

Here is the code from that wiki page:

local pointsDataStore = game:GetService("DataStoreService"):GetDataStore("Points")
 
game.Players.PlayerAdded:Connect(function(player)
	local playerKey = "Player_" .. player.UserId
	-- Give 50 points to players each time they visit
	local success, err = pcall(function()
		pointsDataStore:UpdateAsync(playerKey, function(oldValue) --Notice how the in UpdateAsync you pass in the key, and then a function?
			local newValue = oldValue or 0
			newValue = newValue + 50
			return newValue
		end)
	end)
end)

In your code you're just trying to pass in the value, like you would with SetAsync. UpdateAsync is good for if you need to use the old value, or if you may be updating the same key in multiple places.

6 comments

0

I only started using UpdateAsync for the sole reason of people saying its safer than SetAsync, but I am not yet interested in using the old value before you save it. What if I just want to save the player's data? Do I just put oldValue = newValue and then return the newValue inside the function? Also, what are the strings before the player.UserId for? I use them but I don't know what they do.

0

The string is just to make the key for the player in the datastore. "Player_21467784" <My UserId. You don't even have to do oldValue = newValue and return newValue, just return newValue. Where newValue is the value you're trying to push. Then again, you could just use SetAsync() if you're only going to be access player data from one server at a time.

0

Wow thanks. And is it better to put a string with the UserId in the key or just put the UserId in the key? what difference does that make? Other than that, thanks for helping me with my problem and thankfully, it now saves properly.

0

It doesn't make too much of a difference rather than being able to save multiple values in one datastore. You could do DS:SetAsync("data_" .. player.UserId) and DS:SetAsync("stats_" .. player.UserId) and save them both in one DataStore with different keys

0

Ohh I see, well that clarifies my question, and hopefully I should be better in handling data stores now. Again, thanks for your help.

0

No problem

This discussion is preserved as it was. New answers, comments, and votes are closed.