Minutes Data displaying "nil" instead of the player's minutes

I’ve made a simple hangout game for people to find new friends (nothing new, I know.) I’ve made a global leaderboard that displayed the top 50 players who have the most amount of minutes displayed from 1st, to 50th.

My issue is that whenever I run the game, the leaderboard is displayed the Minutes value as “nil,” instead of the player’s minutes in-game.

What I’ve tried to do is make ipairs go to pairs, but it had no effect. What I also tried to do is make data.Value & data.key, to time.Value & time.key, but it casued much more errors than what the original error showed.

Is there a way to make the leaderboard state the number that the player has? Here is the code that manages the leaderboard:

-- // Script Services
local DataStoreService = game:GetService("DataStoreService")
local TimeData = DataStoreService:GetOrderedDataStore("TimeData")

-- // Script Gui
local Gui = script.Parent.Leaderboard
local Rank = Gui.PlayerRank
local List = Gui.PlayerList

-- // Script Functions
local function SavePlayerData()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local time = player.leaderstats.Time

		local playerKey = "id_"..player.UserId.."_minutes"
		local success, result = pcall(function()
			return TimeData:SetAsync(playerKey, time.Value)
		end)

		if not success then
			warn("⚠ | "..result)
		end
	end
end

local function getTop50Players()
	local isAscending = false
	local pageSize = 50
	local pages = TimeData:GetSortedAsync(isAscending, pageSize)
	local top50 = pages:GetCurrentPage()
	
	local top = {}
	
	for rank, data in pairs(top50) do
		local dataName = data.key
		local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
		local data = data.Value
		
		local currentPlayer = { Player = name, Minutes = data, Rank = rank, }
		table.insert(top, rank, currentPlayer)
	end
	
	return top
end

local function ClearLeaderboard()
	task.spawn(function()
		for _, plrFrame in pairs(List:GetChildren()) do
			if not plrFrame:IsA("Frame") then continue end
			plrFrame:Destroy()
			task.wait(0.25)
		end
	end)
end

local function UpdateLeaderboard()
	SavePlayerData()
	ClearLeaderboard()
	local top50 = getTop50Players()
	
	task.spawn(function()
		for _, plr in ipairs(top50) do
			local frame = Rank:Clone()
			frame.Parent = List
			
			frame.Player.Text = tostring(plr.Player)
			frame.Minutes.Text = tostring(plr.Minutes)
			frame.Rank.Text = tostring(plr.Rank)
			
			frame.Visible = true
			task.wait(0.25)
		end
	end)
end

-- // Script
task.spawn(function()
	while true do
		UpdateLeaderboard()
		for count=60,0,-1 do
			script.Parent.UpdateMessage.Updater.Message.Text = "Updating in.. "..count
			task.wait(1)
		end
	end
end)

Here is the leaderboard in question, minutes is currently displaying “nil” as stated in my message.
image

2 Likes

Try adding some logging to “Minutes = data”, avoid defining two variables with the same name (I see two “data” variables here), and remove that last comma after “Rank = rank”.

Let me know about your findings.

2 Likes

So I re-made the section you were requesting stuff. Here is the piece of code:

for rank, minutes in ipairs(top50) do
	local dataName = minutes.key
	local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
	local data = minutes.Value
	
	local currentPlayer = { Player = name, Minutes = data, Rank = rank }
	table.insert(top, rank, currentPlayer)
	print(currentPlayer.Minutes)
end

The console is also agreeing with the leaderboard is showing nil.

2 Likes

Looks like the way you’re retrieving the data is a bit off. Not really sure but this may help.

-- // Script Services
local DataStoreService = game:GetService("DataStoreService")
local TimeData = DataStoreService:GetOrderedDataStore("TimeData")

-- // Script Gui
local Gui = script.Parent.Leaderboard
local Rank = Gui.PlayerRank
local List = Gui.PlayerList

-- // Script Functions
local function SavePlayerData()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local time = player.leaderstats.Time

		local playerKey = "id_"..player.UserId.."_minutes"
		pcall(function()
			TimeData:SetAsync(playerKey, time.Value)
		end)
	end
end

local function getTop50Players()
	local isAscending = false
	local pageSize = 50
	local pages = TimeData:GetSortedAsync(isAscending, pageSize)
	local top50 = pages:GetCurrentPage()
	
	local top = {}
	
	for rank, entry in pairs(top50) do
		local dataKey = entry.key
		local userId = dataKey:match("id_(%d+)_minutes")
		local playerName = game:GetService("Players"):GetNameFromUserIdAsync(tonumber(userId))
		local minutes = entry.value
		
		local currentPlayer = { Player = playerName, Minutes = minutes, Rank = rank }
		table.insert(top, rank, currentPlayer)
	end
	
	return top
end

local function ClearLeaderboard()
	for _, plrFrame in pairs(List:GetChildren()) do
		if plrFrame:IsA("Frame") then
			plrFrame:Destroy()
		end
	end
end

local function UpdateLeaderboard()
	SavePlayerData()
	ClearLeaderboard()
	local top50 = getTop50Players()
	
	for _, plr in ipairs(top50) do
		local frame = Rank:Clone()
		frame.Parent = List
		
		frame.Player.Text = tostring(plr.Player)
		frame.Minutes.Text = tostring(plr.Minutes)
		frame.Rank.Text = tostring(plr.Rank)
		
		frame.Visible = true
	end
end

-- // Script
task.spawn(function()
	while true do
		UpdateLeaderboard()
		for count = 60, 0, -1 do
			script.Parent.UpdateMessage.Updater.Message.Text = "Updating in.. "..count
			task.wait(1)
		end
	end
end)

Tried not to change much and stick with your post. Didn’t test anything however.

3 Likes

Just tested this part of the script and its fixed! Thanks for the help!

3 Likes

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