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

Unable to cast value to function, how do I fix this?

I was trying to test my datastorage script but whenever it tried to save, it just printed out.

 18:31:19.641 - Unable to cast value to function

I don't know what the problem is and I gave up.

local DataStorageService = game:GetService("DataStoreService")
local MyDataStorage = DataStorageService:GetDataStore("MyDataStorage") -- this gets the data storage,from datastorageservice, sherlock

game.Players.PlayerAdded:Connect(function(player) -- Make the function
	local leaderstats = Instance.new("Folder") -- Then create a folder
	leaderstats.Name = "leaderstats" -- Always name it as "leaderstats", else it will not work. 
	leaderstats.Parent = player
	local Cash = Instance.new("IntValue") -- This will be our first value of our leaderboard which is the "cash".
	Cash.Name = "Cash"
	Cash.Parent = leaderstats
	
	local PlayerUserId = "Player_"..player.UserId -- This is how you would save your data. You can save your data in different ways such as player names
	-- However, saving under a player name isn't helpful as if the player changes their name, they will lose that data
	-- Saving it under UserId is currently the best.
	-- Also, when making leaderboards, you don't have to put in leaderstats at the end, you could define the parent of cash separately.

	-- Load Data
	
	local success, errormessage = pcall (function() -- A Pcall protects you from getting error and prevents scripts from breaking
		-- So basically, what it does is that if it's a success then it would set it equal to the pcall function.
		-- Else if it was an errormessagem it would return.
		 Data = MyDataStorage:UpdateAsync(PlayerUserId) -- Oh yeah, if it's local, it will only be in the scope of a code.
		-- Get ASync will get the sync from the storage
	end)
	
	if success then -- If it is a success then load data
		Cash.Value = Data -- Set our data equal to the current cash
		end
end)

-- SAVE DATA
-- You have to have a data saver in order for your data loader to work.

game.Players.PlayerRemoving:Connect(function(player) -- PlayerRemoving is the exact opposite of PlayerAdded, this applies only when the player
	-- Leaves the game
	local PlayerUserId = "Player_"..player.UserId
	local Data = player.leaderstats.Cash.Value -- This is our data and our data of course is the cash which is what we want to save
	local success,errormessage = pcall(function()
		MyDataStorage:GetAsync(PlayerUserId, Data)-- This will Set a sync, the second parameter is the data you want to save
	end)
	
	if success then
		print ("Data successfully saved!")
	else
		print("There was an error")
		warn (errormessage) -- This would warn us about the error message
	end
end)

1 comment

0

Could you mark my answer as solution? Thanks.

1 answer

You're using UpdateAsync() incorrectly. UpdateAsync takes a function as it's second argument, not a value.

Example of UpdatAsync:

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) -- second argument is a function
			local newValue = oldValue or 0
			newValue = newValue + 50
			return newValue
		end)
	end)
end)

https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/UpdateAsync

2 comments

0

Thanks, fixed my problem.

0

Mark his post as the solution then if it fixed your problem. You should always do this on every question you get a solution to.

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