Unable to cast value to function

Hi.

I am making a Global Leaderboard GUI, and I am using UpdateAsync to update the leaderboards. But it throws this error:

Script:

function updateAsync(Datastore , UserID , Stat)
	
	local success, err = pcall(function()
		Datastore:UpdateAsync(UserID , Stat.Value)
	end)
	
	if not success then
		warn("UpdateAsync failed, with error: " .. err)
	elseif success then
		warn("Updated!")
	end
end
	

while task.wait(10) do
	for _, player in pairs(Players:GetPlayers()) do
		local ParentGoals = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Goals"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentPasses = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Passes"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentSaves = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Saves"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentWins = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Wins"):WaitForChild("Contents"):WaitForChild("Items")
		
		local GoalsStat = player:WaitForChild("Leaderstats"):WaitForChild("Goals")
		local PassStat = player:WaitForChild("Leaderstats"):WaitForChild("Passes")
		local SaveStat = player:WaitForChild("Leaderstats"):WaitForChild("Saves")
		local WinsStat = player:WaitForChild("Leaderstats"):WaitForChild("Wins")
			
		updateAsync(GoalsStore , "User_" .. player.UserId, GoalsStat)
		updateAsync(PassStore , "User_" .. player.UserId, PassStat)
		updateAsync(SaveStore , "User_" .. player.UserId, SaveStat)
		updateAsync(WinStore , "User_" .. player.UserId, WinsStat)

		updateLeaderboard(GoalsStore, ParentGoals , " Scorer" , GoalsLB)
		updateLeaderboard(PassStore, ParentPasses , " Passer" , PassesLB)
		updateLeaderboard(SaveStore, ParentSaves , " Keeper" , SavesLB)
		updateLeaderboard(WinStore, ParentWins , " Winner" , WinsLB)
	end	
end

Any help would be appriciated, thanks!

2 Likes

There is already a topic about it with the same problem

2 Likes

I already read that post. When I use SetAsync, it gives me this warning:

By the way, I am using Datastore2, and was wondering if there is a more conivenent method to make a gui global leaderboard

1 Like

Ah, I see this isn’t an error it means you left too fast you will have to add this function inside of your script.

Add this function inside of the code

game:BindToClose(function()
      for _, Player in pairs(game.Players:GetPlayers()) do
-- put the data saving for the player here (Don't remove the player removing one though
end
end)

I am not trying to update the datastore, I am making a global leaderboard that needs to be updated regularly

The errors stopped by the way (for now, i think)

I am just having issues with the leaderboard not being updated.

2 Likes

By the way @lilmazen1234, I am going off of this tutorial:

Update, found the line that is erroring:

local function updateLeaderboard(dataStore, parent , target , LBToClone)

	
	for _, v in pairs(parent:GetChildren()) do
		if v:IsA("Frame") then 
			v:Destroy() 
		end
	end

	--local success, errorMessage = pcall(function()

		local sortedData = dataStore:GetSortedAsync(false , 50)
		local page = sortedData:GetCurrentPage()

		for rank, data in ipairs(page) do
                  -- this line is erroring (local plrName)
			local plrName = Players:GetNameFromUserIdAsync(tonumber(data.key))
			local value = data.value
			print("The datastore is " ..dataStore.Name .. " and the value is " .. value .."!")

			local isOnLeaderboard = false

			for i,v in pairs(parent:GetChildren()) do
				if v:IsA("Frame") and v.Username.Text == plrName then
					isOnLeaderboard = true
					break
				end
			end

			if value > 0 and not isOnLeaderboard then
				local Template = LBToClone:Clone()
				local Values = LBToClone.Values
				Values.Number.Text = "#"..rank
				Values.Username.Text = plrName
				Values.Value.Text = value
				Template.Parent = parent
			end
			
			if rank == 1 then
				ChatTagsModule.giveChatTag(plrName , target , rank , Color3.fromRGB(251, 255, 0))
			elseif rank == 2 then
				ChatTagsModule.giveChatTag(plrName , target , rank , Color3.fromRGB(34, 255, 0))
			elseif rank == 3 then
				ChatTagsModule.giveChatTag(plrName , target , rank , Color3.fromRGB(0, 255, 255))
			elseif rank > 3 and rank < 51 then
				ChatTagsModule.giveChatTag(plrName , target , rank , Color3.fromRGB(112, 112, 112))
			end
		end
	--end)

	--if not success then
	--	warn("Updating leaderboards failed, with error: " .. errorMessage)
	--end
end

Update 2:

local Remove = string.gsub(data.key , " User_" , "")
local plrName = Players:GetNameFromUserIdAsync(tonumber(Remove))

Fixed it.

1 Like

You have to increase the task.wait(10) to like task.wait(30). This is because of datastore limits.
Change your script to this:

function updateAsync(Datastore , UserID , Stat)
	local success, err = pcall(function()
		Datastore:UpdateAsync(UserID , Stat.Value)
	end)
	
	if not success then
		warn("UpdateAsync failed, with error: " .. err)
	elseif success then
		warn("Updated!")
	end
end
	
while task.wait(30) do
	for _, player in pairs(Players:GetPlayers()) do
		local ParentGoals = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Goals"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentPasses = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Passes"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentSaves = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Saves"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentWins = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Wins"):WaitForChild("Contents"):WaitForChild("Items")
		
		local GoalsStat = player:WaitForChild("Leaderstats"):WaitForChild("Goals")
		local PassStat = player:WaitForChild("Leaderstats"):WaitForChild("Passes")
		local SaveStat = player:WaitForChild("Leaderstats"):WaitForChild("Saves")
		local WinsStat = player:WaitForChild("Leaderstats"):WaitForChild("Wins")
			
		updateAsync(GoalsStore , "User_" .. player.UserId, GoalsStat)
		updateAsync(PassStore , "User_" .. player.UserId, PassStat)
		updateAsync(SaveStore , "User_" .. player.UserId, SaveStat)
		updateAsync(WinStore , "User_" .. player.UserId, WinsStat)

		updateLeaderboard(GoalsStore, ParentGoals , " Scorer" , GoalsLB)
		updateLeaderboard(PassStore, ParentPasses , " Passer" , PassesLB)
		updateLeaderboard(SaveStore, ParentSaves , " Keeper" , SavesLB)
		updateLeaderboard(WinStore, ParentWins , " Winner" , WinsLB)
	end	
end

About this, it still gives this error, even when I wait for 60 seconds.

Here is my code:

function updateAsync(Datastore , UserID , Stat)
	local success, err  = pcall(function() 
		Datastore:SetAsync(UserID , Stat.Value) 
	end)
	
	if not success then
		warn("UpdateAsync failed, with error: " .. err)
	end
end
	

while task.wait(30) do
	for _, player in pairs(Players:GetPlayers()) do
		local ParentGoals = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Goals"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentPasses = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Passes"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentSaves = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Saves"):WaitForChild("Contents"):WaitForChild("Items")
		local ParentWins = player.PlayerGui:WaitForChild("Start"):WaitForChild("Leaderboards"):WaitForChild("Wins"):WaitForChild("Contents"):WaitForChild("Items")
		
		local GoalsStat = player:WaitForChild("Leaderstats"):WaitForChild("Goals" , 5)
		local PassStat = player:WaitForChild("Leaderstats"):WaitForChild("Passes", 5)
		local SaveStat = player:WaitForChild("Leaderstats"):WaitForChild("Saves", 5)
		local WinsStat = player:WaitForChild("Leaderstats"):WaitForChild("Wins", 5)
			
		updateAsync(GoalsStore , player.UserId, GoalsStat)
		updateAsync(PassStore , player.UserId, PassStat)
		updateAsync(SaveStore , player.UserId, SaveStat)
		updateAsync(WinStore , player.UserId, WinsStat)

		updateLeaderboard(GoalsStore, ParentGoals , " Scorer" , GoalsLB)
		updateLeaderboard(PassStore, ParentPasses , " Passer" , PassesLB)
		updateLeaderboard(SaveStore, ParentSaves , " Keeper" , SavesLB)
		updateLeaderboard(WinStore, ParentWins , " Winner" , WinsLB)
	end	
end

Yes, you should also add a wait inbetween each save, because when you save it adds to the queue. You save 4 consecutive times in a row without waiting so the queue will get full.