Attempt to index nil with Stars error

Hello! I have an error that says, "Players.CreatorOfNothing12.PlayerGui.ShopGui.ShopClient:34: attempt to index nil with ‘Stars’'. And also here is the line of code that is giving me issues.

stars.Text = "★"..playerData.Stars

Also, I do have the playerData.

1 Like

Can you show me the full script, or at the least all of the code relevant to it? (i.e. variables, events, functions)

Yes:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))

local GetDataFunc = ReplicatedStorage:WaitForChild("GetData")
local InteractItemFunc = ReplicatedStorage:WaitForChild("InteractItem")

local gui = script.Parent
local exit = gui.Container.Exit
local stars = gui.Container.Stars1
local limit = gui.Container.Limit
local itemsFrame = gui.Container.Items

local playerData = {}

local function GetItemStatus(itemName)
	if table.find(playerData.SelectedTowers, itemName) then
		return "Equipped"
	elseif table.find(playerData.OwnedTowers, itemName) then
		return "Owned"
	else
		return "For Sale"
	end
end

local function interactItem(itemName)
	local data = InteractItemFunc:InvokeServer(itemName)
	if data then
		playerData = data
		updateItems()
	end
end

function updateItems()
	stars.Text = "★"..playerData.Stars
	limit.Text = #playerData.SelectedTowers .. "/3"

	for i, tower in pairs(towers) do

		local oldButton = itemsFrame:FindFirstChild(tower.Name)
		if oldButton then
			oldButton:Destroy()
		end

		local newButton = itemsFrame.TemplateButton:Clone()
		newButton.Name = tower.Name
		newButton.TowerName.Text = tower.Name
		newButton.Image = tower.ImageAsset
		newButton.Visible = true
		newButton.LayoutOrder = tower.Price
		newButton.Parent = itemsFrame

		local status = GetItemStatus(tower.Name)
		if status == "For Sale" then
			newButton.Status.Text = "★"..tower.Price
		elseif status == "Equipped" then
			local UIStroke = Instance.new("UIStroke")

			UIStroke.Color = Color3.new(0,0,0)
			UIStroke.Thickness = 3

			newButton.Status.Text = "✅".." Equipped"
			newButton.Status.TextColor3 = Color3.new(1,1,1)
			newButton.BackgroundColor3 = Color3.new(0,0,0)
		else
			newButton.Status.Text = ""
		end
		newButton.Activated:Connect(function()
			interactItem(tower.Name)
		end)
	end
end

local function toggleShop()
	gui.Container.Visible = not gui.Container.Visible
	if gui.Container.Visible then
		playerData = GetDataFunc:InvokeServer()
		updateItems()
	end
end


local function SetupShop()
	local prompt = Instance.new("ProximityPrompt")
	prompt.RequiresLineOfSight = false
	prompt.ActionText = "Shop"
	prompt.Parent = workspace:WaitForChild("Prox")

	prompt.Triggered:Connect(toggleShop)
	exit.Activated:Connect(toggleShop)
end

SetupShop()

Assuming what the stars variable is equal to is spelled correctly, and by the fact it doesn’t error saying it is nil upon loading (meaning it is spelled correctly), I assume it didn’t have enough time to load in when you are running the function.

Replace all of the following variables with this (and make sure the new one I added is there), and tell me if it works or not after. Hopefully it does:

local container = gui:WaitForChild("Container")
local exit = container:WaitForChild("Exit")
local stars = container:WaitForChild("Stars1")
local limit = container:WaitForChild("Limit")
local itemsFrame = container:WaitForChild("Items")

Wait, the local stars = container:WaitForChild("Stars1") is supposed to be ‘local stars = container:WaitForChild(“Stars”)’. Would that work still?

I just added the WaitForChild on the original code, so that was probably your issue to begin with. If the GuiObject is named “Stars” exactly, then yes, it will. And that also explains why it didn’t work the first time.

1 Like

I still get the same error as last time.

Can you show me all of the descendants of the shop in the explorer?

Here is an image:

Can you show me the error in the output so I can see exactly what it says, just to make sure?

image_2023-07-23_180309302

I think it could be from the playerData instead of the TextLabel now because it should be working with that. Right above the first line in the updateItems function, print the playerData and show me what it prints in the output, please.

I have not finished the saving system. I am just working on a shop that is supposed to show the towers but is not showing because the game stops when the error happens.

I think I see the issue now. I think, at least. Is stars a value in a table, or is it a value tied to an object (i.e. StringValue, IntValue, NumberValue)?

Stars is inside of a table. Is that the problem?

It would be the exact issue. If you haven’t finished the saving and there is nothing to load, it won’t be in the table. It doesn’t exist in the table, so it can’t be set as the text on the TextLabel. Once you finish the saving (and/or loading).

Also looking in the rest of the script, Stars never even gets added to the table. Probably because you haven’t finished the saving, so you can’t load it.

I have another scirpt.

local DataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local database = DataStoreService:GetDataStore("Database")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))

local MAX_SELECTED_TOWERS = 3

local data = {}

local function LoadData(player)
	local success = nil
	local playerData = nil
	local attempt = 1

	repeat
		success, playerData = pcall(function()
			return database:GetAsync(player.UserId)
		end)

		attempt += 1
		if not success then
			warn(playerData)
			task.wait()
		end

	until success or attempt == 3

	if success then
		print("Data saved successfully")
	else
		warn("Unbable to get data for player", player.UserId)
	end
end
players.PlayerAdded:Connect(LoadData)

local function SaveData(player)
	if data[player.UserId] then
		local success = nil
		local playerData = nil
		local attempt = 1

		repeat
			success, playerData = pcall(function()
				return database:UpdateAsync(player.UserId, function()
					return data[player.UserId]
				end)
			end)

			attempt += 1
			if not success then
				warn(playerData)
				task.wait()
			end

		until success or attempt == 3

		if success then
			print("Connection Success")
			if not playerData then
				print("New player, giving default data.")
				playerData = {
					["Stars"] = 50,
					["SelectedTowers"] = {"Soilder"},
					["OwnedTowers"] = {"Soilder", "Trump"}
				}
			end
			data[player.UserId] = playerData
		else
			warn("Unbable to get data for player", player.UserId)
			player:Kick("There was a problem getting your data.")
		end
	else
		warn("No session data for, "..player.UserId)
	end
end
players.PlayerRemoving:Connect(SaveData)

local function GetItemStatus(player, itemName)
	local playerData = data[player.UserId]
	if table.find(playerData.SelectedTowers, itemName) then
		return "Equipped"
	elseif table.find(playerData.OwnedTowers, itemName) then
		return "Owned"
	else
		return "For Sale"
	end
end

ReplicatedStorage.InteractItem.OnServerInvoke = function(player, itemName)
	local shopItem = towers[itemName]
	local playerData = data[player.UserId]
	if shopItem and playerData then
		local status = GetItemStatus(player, itemName)
		
		if status == "For Sale" and shopItem.Price <= playerData.Stars then
			playerData.Stars -= shopItem.Price
			table.insert(playerData.OwnedTowers, shopItem.Name)
		elseif status == "Owned" then
			table.insert(playerData.SelectedTowers, shopItem.Name)
			if #playerData.SelectedTowers > MAX_SELECTED_TOWERS then
				table.remove(playerData.SelectedTowers, 1)
			end
		elseif status == "Equipped" then
			if #playerData.SelectedTowers > 1 then
				local towerToRemove = table.find(playerData.SelectedTowers, itemName)
				table.remove(playerData.SelectedTowers, towerToRemove)
			end		
		end
		
		return playerData
	else
		warn("Tower/player data does not exist")
	end
	return false
end

ReplicatedStorage.GetData.OnServerInvoke = function(player)
	return data[player.UserId]
end

That is the ShopServer.

Never Mind, I fixed the error.

1 Like

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