Why is this nil?

Im trying to make an inventory system for my tower defense game and I made this function to find the tower in a dictionary:

	type tower = {Name: string, ImageAsset: string, Rarity: string}
local function getTowerByKey(key: string): tower?
	for _, rarity in pairs(towers) do
		local tower = rarity[key]
		if tower then return tower end
	end
	return nil
end

(I did it like this because the table looks something like this)

["Common"] = {
			["CCTV-Man"] = {
				["Name"] = "CCTV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13749054780",
			["Rarity"] = "Common"

			},
			["Speakerman"] = {
				["Name"] = "Speakerman",
			["ImageAsset"] = 'http://www.roblox.com/asset/?id=13749300689',
			["Rarity"] = "Common"

			},
			["TV-Man"] = {
				["Name"] = "TV-Man",
				["ImageAsset"] = "http://www.roblox.com/asset/?id=13767180458",
				["Rarity"] = "Common"
			},
	},

Anyways when I call the function, it returns nil but only when I do it with the players SelectedTowers but it works fine with the OwnedOnes, heres the code btw:

function updateItems()
	print(playerData)
	
	

	for i, key in pairs(playerData.OwnedTowers) do
		local tower = getTowerByKey(key)
		
		--find old button
		local oldButton = inventoryFrame:FindFirstChild(tower.Name)
		if oldButton then
			oldButton:Destroy()
		end

		--creating new button
		
		local newButton = template:Clone()
		newButton.Name = tower.Name
		newButton.Image = tower.ImageAsset	

		newButton.Parent = inventoryFrame
		
		local towerfromRs = replicatedStorage.Towers:FindFirstChild(tower.Name)
		
		newButton.LayoutOrder = (towerfromRs.Config.Price.Value) + 999999999
		
		

		local status = getItemStatus(tower.Name)
		
		if status == "Equipped" then
			print(newButton.Name.." is equipped!")
		else
			print(newButton.Name.." is owned!")
		end

		newButton.Activated:Connect(function()
			interactItem(tower.Name)
		end)
	end
	
	for i, selectedKey in pairs(playerData.SelectedTowers) do
		print(selectedKey)
		local selectedTower = getTowerByKey(selectedKey)
		print(selectedTower)

		--find old button
		local oldButton = inventoryFrame:FindFirstChild(selectedTower.Name)
		if oldButton then
			oldButton:Destroy()
		end

		--creating new button

		local newButton = template:Clone()
		newButton.Name = selectedTower.Name
		newButton.Image = selectedTower.ImageAsset	

		newButton.Parent = inventoryFrame

		local towerfromRs = replicatedStorage.Towers:FindFirstChild(selectedTower.Name)

		newButton.LayoutOrder = (towerfromRs.Config.Price.Value)



		local status = getItemStatus(selectedTower.Name)

		if status == "Equipped" then
			print(newButton.Name.." is equipped!")
		else
			print(newButton.Name.." is owned!")
		end

		newButton.Activated:Connect(function()
			interactItem(selectedTower.Name)
		end)
	end
end

The variable “SelectedTower” returns nil. Any help is appreciated, thanks!

2 Likes

I’m pretty sure its because your trying to return the tower in a for loop so its not actually returning the tower as the return of the function

local towers = {
	["Common"] = {
		["CCTV-Man"] = {
			["Name"] = "CCTV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13749054780",
			["Rarity"] = "Common"

		},
		["Speakerman"] = {
			["Name"] = "Speakerman",
			["ImageAsset"] = 'http://www.roblox.com/asset/?id=13749300689',
			["Rarity"] = "Common"

		},
		["TV-Man"] = {
			["Name"] = "TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13767180458",
			["Rarity"] = "Common"
		},
	},
}

type tower = {Name: string, ImageAsset: string, Rarity: string}

local function getTowerByKey(key: string): tower?
	local Tower = nil
	for _, rarity in pairs(towers) do
		Tower = rarity[key]
	end
	return Tower
end

print(getTowerByKey("TV-Man"))

It gave me this error again
image
I thought it was because theres other rarities and it happened to be that the last rarity it was in was incorrect so I did this

type tower = {Name: string, ImageAsset: string, Rarity: string}
local function getTowerByKey(key: string): tower?
	local Tower = nil
	for _, rarity in pairs(towers) do
		if table.find(rarity,key) then
			Tower = rarity[key]
		end
	end
	return Tower
end

But now everything returns as nil?

2 Likes

i disagree you are wrong here

local towers={["test"]="hello world!"}
function GetTower(name)
      for i,v in pairs(towers) do
             if i == name then
                   return v
            end
      end
end
print(GetTower("test")) --prints hello world

i tested in studio and it did print out “hello world”

3 Likes

can you please show InventoryClient source code?

1 Like

What do you mean source code??? That is from the inventory client

1 Like

By the way, “towers” refers to this module:

local TowerShop = {
	
		["Common"] = {
			["CCTV-Man"] = {
				["Name"] = "CCTV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13749054780",
			["Rarity"] = "Common"

			},
			["Speakerman"] = {
				["Name"] = "Speakerman",
			["ImageAsset"] = 'http://www.roblox.com/asset/?id=13749300689',
			["Rarity"] = "Common"

			},
			["TV-Man"] = {
				["Name"] = "TV-Man",
				["ImageAsset"] = "http://www.roblox.com/asset/?id=13767180458",
				["Rarity"] = "Common"
			},
	},
	
	
	
	["Rare"] = {
		["CameraWoman"] = {
			["Name"] = "CameraWoman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14203187739",
			["Rarity"] = "Rare"
		},
		["Ninja Cameraman"] = {
			["Name"] = "Ninja Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14275563102",
			["Rarity"] = "Rare"

		},
		["Large Cameraman"] = {
			["Name"] = "Large Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14343247261",
			["Rarity"] = "Rare"

		},
		["Scientist Cameraman"] = {
			["Name"] = "Scientist Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13891532317",
			["Rarity"] = "Rare"

		},
		["Beach Cameraman"] = {
			["Name"] = "Beach Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13937810342",
			["Rarity"] = "Rare"

		},
	},
	
	["Legendary"] = {
		["TitanSpeakerman"] ={
			["Name"] = "TitanSpeakerman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13762818728",
			["Rarity"] = "Legendary"
		},

		["Titan TV-Man"] = {
			["Name"] = "Titan TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13901550336",
			["Rarity"] = "Legendary"

		},


		["Titan Cameraman"] = {
			["Name"] = "Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14078345674",
			["Rarity"] = "Legendary"

		},
		["TV-Woman"] = {
			["Name"] = "TV-Woman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14077842545",
			["Rarity"] = "Legendary"

		},
		["Upgraded Titan Cameraman"] = {
			["Name"] = "Upgraded Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14168160010",
			["Rarity"] = "Legendary"

		},
	},

	
	
}

return TowerShop

2 Likes

I’m not sure but I think the problem is in a other script

bro i copy pasted your script it works for me whats wrong???

I dont know this thing just works for me
LocalScript named client in ReplicatedFirst

local towers=require(game:GetService("ReplicatedStorage"):WaitForChild("towers"))
type tower = {Name: string, ImageAsset: string, Rarity: string}
local function getTowerByKey(key: string): tower?
	for _, rarity in pairs(towers) do
		if rarity[key] then
			return rarity[key]
		end
	end
end
print(getTowerByKey("CCTV-Man"))

towers ModuleScript inside ReplicatedStorage

local TowerShop = {

	["Common"] = {
		["CCTV-Man"] = {
			["Name"] = "CCTV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13749054780",
			["Rarity"] = "Common"

		},
		["Speakerman"] = {
			["Name"] = "Speakerman",
			["ImageAsset"] = 'http://www.roblox.com/asset/?id=13749300689',
			["Rarity"] = "Common"

		},
		["TV-Man"] = {
			["Name"] = "TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13767180458",
			["Rarity"] = "Common"
		},
	},



	["Rare"] = {
		["CameraWoman"] = {
			["Name"] = "CameraWoman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14203187739",
			["Rarity"] = "Rare"
		},
		["Ninja Cameraman"] = {
			["Name"] = "Ninja Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14275563102",
			["Rarity"] = "Rare"

		},
		["Large Cameraman"] = {
			["Name"] = "Large Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14343247261",
			["Rarity"] = "Rare"

		},
		["Scientist Cameraman"] = {
			["Name"] = "Scientist Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13891532317",
			["Rarity"] = "Rare"

		},
		["Beach Cameraman"] = {
			["Name"] = "Beach Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13937810342",
			["Rarity"] = "Rare"

		},
	},

	["Legendary"] = {
		["TitanSpeakerman"] ={
			["Name"] = "TitanSpeakerman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13762818728",
			["Rarity"] = "Legendary"
		},

		["Titan TV-Man"] = {
			["Name"] = "Titan TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13901550336",
			["Rarity"] = "Legendary"

		},


		["Titan Cameraman"] = {
			["Name"] = "Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14078345674",
			["Rarity"] = "Legendary"

		},
		["TV-Woman"] = {
			["Name"] = "TV-Woman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14077842545",
			["Rarity"] = "Legendary"

		},
		["Upgraded Titan Cameraman"] = {
			["Name"] = "Upgraded Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14168160010",
			["Rarity"] = "Legendary"

		},
	},



}

return TowerShop
1 Like

there maybe is a spelling error in the table I don’t know for sure

table code:

local TowerShop = {

	["Common"] = {
		["CCTV-Man"] = {
			["Name"] = "CCTV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13749054780",
			["Rarity"] = "Common"

		},
		["Speakerman"] = {
			["Name"] = "Speakerman",
			["ImageAsset"] = 'http://www.roblox.com/asset/?id=13749300689',
			["Rarity"] = "Common"

		},
		["TV-Man"] = {
			["Name"] = "TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13767180458",
			["Rarity"] = "Common"
		},
	},



	["Rare"] = {
		["CameraWoman"] = {
			["Name"] = "CameraWoman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14203187739",
			["Rarity"] = "Rare"
		},
		["Ninja Cameraman"] = {
			["Name"] = "Ninja Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14275563102",
			["Rarity"] = "Rare"

		},
		["Large Cameraman"] = {
			["Name"] = "Large Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14343247261",
			["Rarity"] = "Rare"

		},
		["Scientist Cameraman"] = {
			["Name"] = "Scientist Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13891532317",
			["Rarity"] = "Rare"

		},
		["Beach Cameraman"] = {
			["Name"] = "Beach Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13937810342",
			["Rarity"] = "Rare"

		},
	},

	["Legendary"] = {
		["TitanSpeakerman"] ={
			["Name"] = "TitanSpeakerman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13762818728",
			["Rarity"] = "Legendary"
		},

		["Titan TV-Man"] = {
			["Name"] = "Titan TV-Man",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=13901550336",
			["Rarity"] = "Legendary"

		},


		["Titan Cameraman"] = {
			["Name"] = "Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14078345674",
			["Rarity"] = "Legendary"

		},
		["TV-Woman"] = {
			["Name"] = "TV-Woman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14077842545",
			["Rarity"] = "Legendary"

		},
		["Upgraded Titan Cameraman"] = {
			["Name"] = "Upgraded Titan Cameraman",
			["ImageAsset"] = "http://www.roblox.com/asset/?id=14168160010",
			["Rarity"] = "Legendary"

		},
	},



}

return TowerShop

I’m not sure but you can see where the script stops by using print()

1 Like

i swear to god this ran for me no issues in studio not a single error

Zrzut ekranu (16)

1 Like

Ok now it works and prints the table but its just not making any buttons but thats probably unrelated, thanks though!

1 Like

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