Leaderboard UI script won't work

I was watching a tutorial on how to create a global leaderboard script which displays players with the most gems from leaderstats in order, however it doesn’t seem to work. I have a LocalScript inside of the scrolling frame, a leaderstats script for the gems and another Leaderboard script in ServerScriptService.

image
image

Leaderboard script:

local newEvent = Instance.new("RemoteEvent")
newEvent.Name = "Leaderboard"
newEvent.Parent = game:GetService("ReplicatedStorage")

local data = game:GetService("DataStoreService"):GetOrderedDataStore("Leaderboard")

local storedDataName = "Gems"

wait(5)
while true do
	for i, player in pairs(game.Players:GetPlayers()) do
		local leaderstats = player:FindFirstChild("Leaderboard")
		if leaderstats then
			local gems = leaderstats:FindFirstChild(storedDataName)
			if gems then
				pcall(function()
					data:UpdateAsync(player.UserId, function(oldVal)
						return gems.Value
					end)
				end)
			end
		end
	end

	-- Fetch and update leaderboard data
	local pages = data:GetSortedAsync(false, 25)
	local top = pages:GetCurrentPage()
	local datab = {}
	local on = 1
	for i, data in ipairs(top) do
		local userid = data.key
		local gems = data.Value
		local name = "Loading..."
		local s, e = pcall(function()
			name = game.Players:GetNameFromUserIdAsync(userid)
		end)
		if not s then
			warn("Error getting name for " .. userid .. ". Error:" .. e)
		end
		local image = "https://roblox.com/headshot-thumbnail/image?userId=" .. userid .. "&width=150&height=150&format=png"
		datab[on] = {
			["Name"] = name,
			["Image"] = image,
			["Gems"] = gems
		}
		on = on + 1
	end
	newEvent:FireAllClients(datab)

	wait(5) -- Reduce wait time
end

GemHandler (leaderstats) script:

local DataStoreService = game:GetService("DataStoreService")
local GemStore = DataStoreService:GetDataStore("GemStore")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	local userID = Player.UserId
	local Currency = GemStore:GetAsync(userID)

	-- Create leaderstats folder if it doesn't exist
	local leaderstats = Player:FindFirstChild("leaderstats")
	if not leaderstats then
		leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = Player
	end

	-- Check if Currency exists, set default value if not
	if not Currency then
		Currency = 0
	end

	-- Set Gems value in leaderstats
	local gems = leaderstats:FindFirstChild("Gems")
	if not gems then
		gems = Instance.new("IntValue")
		gems.Name = "Gems"
		gems.Value = Currency
		gems.Parent = leaderstats
	else
		gems.Value = Currency
	end

	-- Connect a function to update the datastore when Gems value changes
	gems.Changed:Connect(function(NewValue)
		GemStore:SetAsync(userID, NewValue)
	end)
end)

LocalScript in frame:

local event = game:GetService("ReplicatedStorage"):WaitForChild("Leaderboard")
local sample = script:WaitForChild("Sample")
local frame = script.Parent
local ui = frame:WaitForChild("UI")
local function createFrame(number,name,image,val)
	local color = Color3.new(1,1,1)
	if number == 1 then
		color = Color3.new(1,1,0)
	elseif number == 2 then
		color = Color3.new(0.9,0.9,0.9)
	elseif number == 3 then
		color = Color3.fromRGB(166,122,0)
	end
	
	local new = sample:Clone()
	new.Image.Image = image
	new.Image.Num.Text = number
	new.Name.Text = name
	new.Gems.Text = val
	new.LayoutOrder = number
	new.Image.Num.TextColor3 = color
	new.Gems.TextColor3 = color
	new.Name.TextColor3 = color
	new.Parent = frame
end

event.OnClientEvent:Connect(function(data)
	for i,v in pairs(frame:GetChildren()) do
		if v.Name == "Sample" then
			v:Destroy()
		end
	end
	for i,v in pairs(data) do
		local name = data[i]["Name"]
		local image = data[i]["Image"]
		local val = data[i]["Gems"]
		createFrame(i,name,image,val)
	end
	wait(0.1)
	frame.CanvasSize = UDim2.new(0,0,0,ui.AbsoluteContentSize.Y)
end)