How to get a table from the server to client

Hello, I am trying to make a remote event module for myself and I can’t get a table from the client to server I tried remote events too here is the script:

function Manager:BindClientEvents(player,functions)
    for i, v in pairs(functions) do
        Listeners[i] = v
    end

    for i, v in pairs(Listeners) do
        print(i,v)
    end

    print(Listeners)

    script.SendFunctionsToClient.OnServerInvoke = function()
        return Listeners
    end
end

function Manager:OnClientEvent(player)
    script.RemoteEvent.OnClientEvent:Connect(function(name)
        print("Picked up")
        local Functions = script.SendFunctionsToClient:InvokeServer()

        print(Functions)

        for i, v in pairs(Functions) do
            if v == name then
                print("Found")
            else
                print("not found",i.."__"..v)
            end
        end
    end)
end

function Manager:FireClient(player,firename)
    script.RemoteEvent:FireClient(player,firename)
    print("Fired")
end

All it returns is a blank table when it’s not a blank table.

I can’t understand your script’s types so I will list what I know of this issue

  1. You are not allowed to send client side instances to the server, they will always be nil
  2. You are not allowed to send mixed keyed tables, convert your table keys to strings
  3. Tables with a [1] key will be treated as an Array, ensure no gaps i.e. {“first”, nil, “third”} [2] is the gap

Hey to help you help me I will send you the scripts:

Module script:

local RunService = game:GetService("RunService")
local Manager = {}
local Listeners = {}

function Manager:ServerInit()
	if RunService:IsClient() then
		return
	end

    local RemoteEvent = Instance.new("RemoteEvent",script)

    local SendFunctionsToClient = Instance.new("RemoteFunction")
    SendFunctionsToClient.Name = "SendFunctionsToClient"
    SendFunctionsToClient.Parent = script
end

function Manager:BindClientEvents(player,functions)
    for i, v in pairs(functions) do
        Listeners[i] = v
    end

    for i, v in pairs(Listeners) do
        print(i,v)
    end

    print(Listeners)

    script.SendFunctionsToClient.OnServerInvoke = function()
        return Listeners
    end
end

function Manager:OnClientEvent(player)
    script.RemoteEvent.OnClientEvent:Connect(function(name)
        print("Picked up")
        local Functions = script.SendFunctionsToClient:InvokeServer()

        print(Functions)

        for i, v in pairs(Functions) do
            if v == name then
                print("Found")
            else
                print("not found",i.."__"..v)
            end
        end
    end)
end

function Manager:FireClient(player,firename)
    script.RemoteEvent:FireClient(player,firename)
    print("Fired")
end

return Manager

server script

local Module = require(game.ReplicatedStorage.Modules.EventManager)

game.Players.PlayerAdded:Connect(function(player)
    Module:ServerInit()

    Module:BindClientEvents(
        player,
        {
            ["Hello"] = function()
                print("Success!!!")
            end
        }
    )

    Module:FireClient(player,"Hello")
end)

local script

wait(3)
local Module = require(game.ReplicatedStorage.Modules.EventManager)
Module:OnClientEvent(game.Players.LocalPlayer)

It’s probably not reaching the player because of the initial wait(3), the client needs to be connected to receive events from the server. I don’t think this script is a good idea, going back and forth with so many events will be much slower and more complicated to keep up than just sharing a remote event over replicated storage.

Yes but I was thinking of an idea:

You can pass in a function in a module script like this: Module:FireClient(“Test”)

it would fire the client and the client would look through a table of functions and see if “Test” matches one of the function names

then it would run that function

local funcs = {
    ["Test"] = function()
        print("success!")
    end,
    ["Hello"] = function(name: string)
        print("Hello", name)
    end
}

event.OnClientEvent:Connect(function(functionName, ...)
    local func = funcs[functionName]
    assert(func, "Invalid function name " .. functionName)
    func(...)
end)

This will achieve the same thing, and functions can be added to it.

Maybe the problem is your trying to bind server functions to client events. The client cannot call server functions without invoke, but if you are telling the client to start an invoke you should cut the middle man out. Do as much as you can before crossing the client-server boundary, the back and forth talking is very bad.

Thank you very much for helping and thanks for the advice as well!