Attempt to index nil with number

So I’m trying to code an inventory system, and I want a button to show wether or not a value in a table is set to true or false. Currently, I’m getting the error above when retrieving the data

Client:

local data2

local function getData()
	retrieve:FireServer()
	retrieve2.OnClientEvent:Connect(function(data)
		print("Set data!")
		data2 = data
	end)
end

invenshowevent.Event:Connect(function()
	getData()
	if data2[1] == true then -- Errors here
		script.Parent.Visible = true
	end
end)

Server:

Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local otherData = Instance.new("Folder")
	otherData.Name = "otherData"
	otherData.Parent = player
	
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = leaderstats
	
	local Wins = Instance.new("IntValue")
	Wins.Name = "Wins"
	Wins.Parent = leaderstats
	
	local itemsData = {
		false
	}
	
	
	
	local data, data2, data3
	local success, errormessage = pcall(function()
		data = plrData:GetAsync(player.UserId.."-cash")
		data2 = plrData:GetAsync(player.UserId.."-wins")
		data3 = plrData:GetAsync(player.UserId.."-items")
		print(data, data2)
	end)
	
	if success then
		print("Data Loaded!")
		if data and data2 ~= nil then
			Cash.Value = data
			Wins.Value = data2
		end
		if data3 ~= nil then
			itemsData = data3
		else
			itemsData = {
				false
			}
			plrData:SetAsync(player.UserId.."-items", itemsData)
			print("itemsData defaulted")
		end
	else
		print("Couldn't Load Data")
		warn(errormessage)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		plrData:SetAsync(player.UserId.."-cash", player.leaderstats.Cash.Value)
		plrData:SetAsync(player.UserId.."-wins", player.leaderstats.Wins.Value)
		plrData:SetAsync(player.UserId.."-items", player.leaderstats.itemsData)
	end)
	if not success then
		warn(errormessage)
	else
		print("Data Saved!")
	end
end)

retrieveclient.OnServerEvent:Connect(function(player)
	local data = plrData:GetAsync(player.UserId.."-items")
	retrieveclient2:FireClient(player, data)
end)

Your getData() function does not wait for server to respond. It makes a new connection (which is in itself a problem, as you will have a new redundant connection every time this function is used) and finishes execution.

This way by the time server responds, your invenshowevent function has already crashed.

Ideal solution will be to use RemoteFunction, as those yield until server responds. Your code can also be fixed using events, do not get me wrong, but those are not designed for two way communication.

-- client (remove getData() function)

local GetData = game.ReplicatedStorage:WaitForChild('GetData')

invenshowevent.Event:Connect(function()
	data2 = GetData:InvokeServer()
	if data2[1] == true then -- Errors here
		script.Parent.Visible = true
	end
end)

-- server
-- do it this way or create remote function manually
local GetData = Instance.new('RemoteFunction')
GetData.Name = 'GetData'
GetData.Parent = game.ReplicatedStorage

-- consider adding pcall to your async function as well as error handling
local function OnGetData(player) --edit: changed plr to player
	return plrData:GetAsync(player.UserId.."-items")
end
GetData.OnServerInvoke = OnGetData

-- remove this
--[[retrieveclient.OnServerEvent:Connect(function(player)
	local data = plrData:GetAsync(player.UserId.."-items")
	retrieveclient2:FireClient(player, data)
end)--]]
1 Like

This code fails silently unfortunately