Buy buttons not working

I’m trying to make a shop but whenever I click my buy buttons nothing happens.

Invoking script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Functions = ReplicatedStorage.Functions

local function UpdateText(text,message,td)
	task.spawn(function()
		text.Text = message
		task.wait(td)
		text.Text = "Buy"
	end)
end

local Purchasing = {}


function Purchasing:Init(option,tool)
	local bb = option.BuyButton
	local invoke = Functions.ToServer:InvokeServer("PurchaseItem",tool.Name)
	if invoke == "Success" then
		UpdateText(bb,"Purchase complete!",2)
	elseif invoke == "Failure" then
		UpdateText(bb,"Insufficient funds",2)
	end
end

return Purchasing

Invoked code:

	Functions.ToServer.OnServerInvoke = function(player,signal,toolName)
		if typeof(toolName) ~= "string" then return end
		if signal == "PurchaseItem" then
			print("Happened")
			local tool = Tools:FindFirstChild(toolName)
			local price = tool:GetAttribute("Price")
			if player.leaderstats.Money.Value >= price then
				local newTool = tool:Clone()
				player.leaderstats.Money.Value -= price
				newTool.Parent = player.Backpack
				return "Success"
			else
				return "Failure"
			end
		end
	end

When I click on a buy button, I can print out anything, but no signal is received from the server invoke, so it continuously returns nil.

There is an even else statement to show that anything but having higher money than price would result in failure. Instead though I get nil, any ideas?

have you tried printing the toolname type or checking the toolname type? maybe its receiving nil.

if you have a chance,can you send me a copy of your game?

i think you didnt gave the invoked code fully.theres no variable named Tools.

1 Like

I showed you everything relevant to the issue, there aren’t any errors on missing variables yet its still not working. All the arguments exist but where you see print(“Happened”) in the Invoked code, it doesn’t ever print.

Functions.ToServer.OnServerInvoke = function(player,signal,toolName)
		if typeof(toolName) ~= "string" then return end
		if signal == "PurchaseItem" then
			print("Happened")
			local tool = Tools:FindFirstChild(toolName)
			local price = tool:GetAttribute("Price")
			if player.leaderstats.Money.Value >= price then
				local newTool = tool:Clone()
				player.leaderstats.Money.Value -= price
				newTool.Parent = player.Backpack
				return "Success"
			else
				return "Failure"
			end
		end
	end

There’s no Tools variable.

I gotta train my english i literally didnt understood sorry about that i suck in the english pls accept my sorry im bad at english.

1 Like

Are you 100% sure you’re even calling the remote function? Maybe I’m blind, but I can’t see you calling Purchasing:Init anywhere.

4 Likes

he actually does.i dont know >:(

1 Like

try this here:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Tools = game:GetService("ServerStorage"):WaitForChild("Tools")  -- Assuming your tools are stored in ServerStorage.
local Functions = ReplicatedStorage:WaitForChild("Functions")

Functions.ToServer.OnServerInvoke = function(player, signal, toolName)
	if signal ~= "PurchaseItem" or not toolName then return end
	local tool = Tools:FindFirstChild(toolName)
	if not tool then return "Failure" end

	local price = tool:GetAttribute("Price")
	if not price then return "Failure" end

	if player.leaderstats.Money.Value >= price then
		player.leaderstats.Money.Value -= price
		local newTool = tool:Clone()
		newTool.Parent = player.Backpack
		return "Success"
	else
		return "Failure"
	end
end
1 Like

I’m not sure if he is. He defines function Purchasing:Init, in which he calls ToServer, but I don’t see him ever calling Purchasing:Init. OP should try putting a print statement where he is trying to call ToServer and see if it prints.

1 Like
function Purchasing:Init(option,tool)
	print(option,tool)
	local bb = option.BuyButton
	local invoke = Functions.ToServer:InvokeServer("PurchaseItem",tool.Name)
	print(invoke)
	if invoke == "Success" then
		UpdateText(bb,"Purchase complete!",2)
	elseif invoke == "Failure" then
		UpdateText(bb,"Insufficient funds",2)
	end
end

invoke = nil
option,tool are not nil

I have all the variables right and defined, if I didn’t I’d get an error.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage.Remotes
local Bindables = ReplicatedStorage.Bindables
local Items = ReplicatedStorage.Items
local Tools = Items.Tools
local Assets = ReplicatedStorage.Assets
local GUI = Assets.GUI.Shop

local ShopGui = script.ShopGui
local Backdrop = ShopGui.Backdrop
local ExitButton = Backdrop.ExitButton
local Background = Backdrop.Background
local Layout = Background.Layout

local InfoGui = script.InfoGui

local Info = require(script.Info)
local Purchasing = require(script.Purchasing)

local ShopOptions = {}

local ShopLayout = {}

local function PressBuyButton(option,tool)
	return function()
		print("Clicked")
		Purchasing:Init(option,tool)
	end
end

local function HoveredOption(tool)
	return function()
		InfoGui.Enabled = true
		Info.new(tool):Init()
	end
end

local function LeavedOption()
	InfoGui.Enabled = false
	Info:Clean()
end

function ShopLayout:InitOption(tool)
	local option = GUI.Option:Clone()
	option.Title.Text = tool.Name
	option.Parent = Layout
	option.InfoHover.MouseEnter:Connect(HoveredOption(tool))
	option.InfoHover.MouseLeave:Connect(LeavedOption)
	option.BuyButton.MouseButton1Up:Connect(PressBuyButton(option,tool))
	return option
end

function ShopLayout:CreateOptions()
	for i,v in Tools:GetChildren() do
		local order = v:GetAttribute("Order")
		local option = self:InitOption(v)
		option.Name = tostring(order)
		table.insert(ShopOptions,order)
	end
	table.sort(ShopOptions,function(a,b) return a < b end)
end

function ShopLayout:Init()
	self:CreateOptions()
	Bindables.OnClient.Event:Connect(function(signal)
		if signal == "ShopGuiEnabled" then
			ShopGui.Enabled = true
		end
	end)
	ExitButton.MouseButton1Up:Connect(function()
		ShopGui.Enabled = false
		Remotes.ToServer:FireServer("ReverseShopChanges")
	end)
end

return ShopLayout

This is the script where I call Purchasing:Init

It didn’t do anything, invoke still equal to nil

  • Check Functions.ToServer Reference: Confirm that Functions.ToServer points to the correct RemoteFunction. It’s not shown in the provided code, so ensure this reference is correctly initialized elsewhere in your script.

  • Error Handling: Implement error handling around the InvokeServer call to catch any issues. Lua’s pcall can be useful for this:

    local success, result = pcall(function()
        return Functions.ToServer:InvokeServer("PurchaseItem", tool.Name)
    end)
    if success then
        invoke = result
    else
        print("Error calling server:", result)
    end
    
  • Debug Output: Increase the use of print statements around the invoke assignment to confirm the flow of execution and whether the InvokeServer call is made as expected.

It points to the correct RemoteFunction, my game only uses 1 function which is ToServer.

The pcall method didn’t work for me:

function Purchasing:Init(option,tool)
	local bb = option.BuyButton
	local invoke
	local success, result = pcall(function()
		return Functions.ToServer:InvokeServer("PurchaseItem",tool.Name)
	end)
	if success then
		invoke = result
		if result == "Success" then
			UpdateText(bb,"Purchase complete!",2)
		elseif invoke == "Failure" then
			UpdateText(bb,"Insufficient funds",2)
		end
	else
		warn("There was an error")
	end
end

I’d also like to mention buying used to work before its just not working anymore.

Server side handler check

local Functions = game:GetService("ReplicatedStorage"):WaitForChild("Functions")
local ToServer = Functions:WaitForChild("ToServer")

ToServer.OnServerInvoke = function(player, action, itemName)
    if action == "PurchaseItem" then
        -- Logic to handle the item purchase
        -- Ensure to return "Success" or "Failure" based on the purchase outcome
    end
end

And error handling and debugging

print("Before pcall")
local success, result = pcall(function()
    return Functions.ToServer:InvokeServer("PurchaseItem", tool.Name)
end)
print("After pcall:", success, result)

Keep debugging and error handling and the outcome or output explain it here and that should be your solution and try to fix that outcome from that point to prevent other issues.

I think there is some other underlying cause of this issue, everything in PurchaseItem it never happens.

There is no point in putting it in a pcall because it will still never work on the server, because its not invoked.

Describe the underlying issue if you have found it

What I say is “Invoked code” on the post never happens and returns nil to the invoke variable on the client.

Ensure Proper Client Invocation

On the client side, ensure you are correctly invoking the RemoteFunction and handling its return value:

local remoteFunction = game.ReplicatedStorage:WaitForChild("YourRemoteFunctionName")
local success, result = pcall(function()
    return remoteFunction:InvokeServer(...)
end)

if success then
    print("Received from server:", result)
else
    warn("Invoke failed:", result)
end
	local bb = option.BuyButton
	local success, result = pcall(function()
		return Functions:WaitForChild("ToServer"):InvokeServer("PurchaseItem",tool.Name)
	end)
	if success then
		if result == "Success" then
			UpdateText(bb,"Purchase complete!",2)
		elseif result == "Failure" then
			UpdateText(bb,"Insufficient funds",2)
		end
	end

I don’t think a pcall is gonna solve this issue because it doesn’t actually stop it from being nil. It still doesn’t work.