Module script not returning value

This code is trying to attempt to grab a player’s inventory based with the given player argument. It fires a remote event to get the inventory, then the other script fires it back and gives the table. Right now though, the script that’s using it is printing nil. Why is this?
Module

local TheValleyFunctions = {}

function TheValleyFunctions.GetInventory(Player)
	game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
	game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(Inventory)
		return Inventory
	end)
	
	end
return TheValleyFunctions

Script it’s used in

...
local function Map()
	local GetInventory = TheValleyFunctions.GetInventory(game.Players.LocalPlayer)
		local CurrentItem
		local CurrentAmount
	local SlotNum
	print(GetInventory)
...

As far as I’m aware, the issues arise from the fact Return will get whatever inventory is and return it within the OnClientEvent function, meaning nothing is truly returned to the GetInventory function. You might be able to fix it with this, but I foresee issues with timing which may be your next problem.

function TheValleyFunctions.GetInventory(Player)
	game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
	local Inventory
    game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(fetchedInventory)
		Inventory = fetchedInventory
	end)
	return Inventory`
end

If this doesn’t work, which I’m not sure if it will, you could also try directly returning the event?

When you say returning the event, do you mean doing something like
return game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent?

Yeah, you can try returning the entire event like that, however that’d still be a bit iffy. I believe the main problem is the fact that this function acts like a wrapper; you may be able to avoid this all together with a bit of refactoring.

There is indeed a timing issue. It returns Inventory before the remote event gets back to the module. I tried fixing it with this:

function TheValleyFunctions.GetInventory(Player)
	game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
	local Inventory
	repeat task.wait() until game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(FetchedInventory)
		print("This happens")
		Inventory = FetchedInventory
	end)
	return Inventory
end

But to no avail.

This also just gave the other script something called “Connection”

return game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(FetchedInventory)
		print("This happens")
		Inventory = FetchedInventory
		return Inventory
	end)
function TheValleyFunctions.GetInventory(Player)
	game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
	local Inventory
        local DB = false
game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(FetchedInventory)
                DB = true
		print("This happens")
		Inventory = FetchedInventory
	end)

	repeat task.wait() until DB ~= false
	return Inventory
end
1 Like

So all that was needed was a debouce to halt the script’s return?

what I did was make a loop until the client fired, when the event fires, the DB variable change to true, which ll make the loop stop and return the inventory, so yes

1 Like

Thank you. I guess the repeat loop I made just listened for the wrong thing to go off.

You could also use RemoteEvent.OnClientEvent:Wait() instead of a repeat loop since this is a local call. :Wait() will return any values given on the next event call. So instead, you could write the code like this:

function TheValleyFunctions.GetInventory(Player)
	game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
	return game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Wait()
end

Also, you could use RemoteFunctions instead of a RemoteEvent for this sort of thing, since you’re calling a RemoteEvent to the server to then send you back data; something that a RemoteFunction handles pretty easily.

This seems a lot simpler. By any chance would you be able to provide an example of how I would use a remote function for this sort of thing?

Here’s how a RemoteFunction would work:

local MapInventory = game.ReplicatedStorage.Inventory.MapInventory

-- Server script
MapInventory.OnServerInvoke = function(player: Player, ...)
	print(...)
	
	local Inventory = nil
	
	-- Code to get your inventory
	
	return Inventory
end


-- LocalScript
local Inventory = MapInventory:InvokeServer("Whatever you would put here")
print(Inventory)

RemoteFunctions also must always return something, otherwise the script calling the RemoteFunction will hang/not continue forward unless in a coroutine/new thread or the function is entirely ran.

1 Like