Attempt to Call a Table Value

Hello scripters! I am trying to make a data store for pets, coins, and whatnot. However, when I try to play the game and add gems, the leaderboard does not use abbreviations such as “K”, “M”, or “B”, and gives an error (the one shown in the title). I am using Format Number to do this. Also, I want to make it so that the Coins do not show up on the leaderboard, but the gems do. Any help on this would be appreciated. Thanks!

Script:

local RS = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local SS = game:GetService("ServerStorage")
local DSS = game:GetService("DataStoreService")

local PlayerData = SS.PlayerData
local Shared = RS.Shared

local FormatNumber = require(Shared.FormatNumber)

local function NewPlayer(Player)
	for _, instance in pairs(PlayerData:GetChildren()) do
		local cloned = instance:Clone()
		cloned.Parent = Player
	end
	
	local StatsFolder = Player.Stats
	local leaderstats = Player.leaderstats
	
	for _, val in pairs(StatsFolder:GetChildren()) do
		leaderstats:FindFirstChild(val.Name).Value = FormatNumber.FormatType(tonumber(val.Value))
		val.Changed:Connect(function()
			leaderstats:FindFirstChild(val.Name).Value = FormatNumber.FormatType(tonumber(val.Value))
		end)
	end
end


local function PlayerLeaving(Player)
	
	
end


Players.PlayerAdded:Connect(NewPlayer)
Players.PlayerRemoving:Connect(PlayerLeaving)

If you need more info, just let me know. Also, anything I try to do for the coins not showing doesnt work. (Almost forgot that the script is not finished yet, but this part needs to be done before the rest will work)

Can you show the FormatNumber module

local Suffixes = {"K", "M", "B", "T"}

local function roundToNearest(n: number, to: number)
	return math.round(n / to) * to
end

local function formatNotation(n: number)
	return string.gsub(string.format("%.1e", n), "+", "")
end

local function formatCommas(n: number)
	local str = string.format("%.f", n)
	return #str % 3 == 0 and str:reverse():gsub("(%d%d%d)", "%1,"):reverse():sub(2) or str:reverse():gsub("(%d%d%d)", "%1,"):reverse()
end

local function formatSuffix(n: number)
	local str = string.format("%.f", math.floor(n))
	str = roundToNearest(tonumber(string.sub(str, 1, 12)), 10) .. string.sub(str, 13, #str)
	local size = #str
	
	local cutPoint = (size-1) % 3 + 1
	local before = string.sub(str, 1, cutPoint) -- (123).4K
	
	local after = string.format("%01.f", string.sub(str, cutPoint + 1, cutPoint + 1)) -- 123.(4)K
	local suffix = Suffixes[math.clamp(math.floor((size-1)/3), 1, #Suffixes)] -- 123.4(K)
	
	if not suffix or n > 9.999e44 then
		return formatNotation(n)
	end
	
	return string.format("%s.%s%s", before, after, suffix)
end

--------------------------------------------------------------------------------

local API = {}

API.FormatType = {
	Notation = "Notation",
	Commas = "Commas",
	Suffix = "Suffix",
}

local function Convert(n: number, FormatType: string)
	n = tonumber(n)
	
	if n < 1e3 or FormatType == nil then
		if FormatType == nil then
			warn("[FormatNumber]: FormatType wasn't given.")
		end
		return tostring(n)
	end
	
	if FormatType == "Notation" then
		return formatNotation(n)
	elseif FormatType == "Commas" then
		return formatCommas(n)
	elseif FormatType == "Suffix" then
		return formatSuffix(n)
	else
		warn("[FormatNumber]: FormatType not found for \"".. FormatType .."\".")
	end
end

setmetatable(API, {
	__call = function(t, ...)
		if t == API then
			return Convert(...)
		end
	end,
})

return API

It’s because API.FormatType is a table, you can’t call a table typically. I think what you meant to do was call setmetatable on API.FormatType, or you meant to call API itself (which was returned from the require call in the script in your op).

ok so im a little confused, but i think i get it. is there a way to change my script to work without rewriting the entire thing?

Yes, you should be able to just call setmetatable on API.FormatTable, not on API, and check if t == API.FormatTable. Or you could just expose the methods directly instead of wrapping them in a metatable.

ok so where would i call setmetatable on API.FormatTable? like i said im a little confused, sorry

Replace the setmetatable(API with setmetatable(API.FormatType

this is what happens

I meant to put FormatType, not FormatTable.

it no longer gives the error! however it still does not show the abbreviation on the leaderboard and gives this (if you saw this from the FormatNumber script)
warn

Yes you need to pass a FormatType when calling it after the number.

i am so sorry for asking, but how would i do that? i am kinda new to making this kind of stuff so apologies if i seem to be asking you for everything

Add a string specifying which format type as another argument.

thank you for all your help! it worked

1 Like

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