How to properly disconnect using Maids

I want to basically have functions connected whenever a new interactable is added. However, I want to be able to disconnect them when said interactable has been destroyed. I’m new to using maids, but I kinda have a vague grasp, which I tried here, however I’m unsure how to disconnect them properly

-- New interactable added
local function NewInteractable(child)
	local NewMaid = Maid.new()
	
	NewMaid:GiveTask(child.Control.MouseEnter:Connect(function()
		
	end))
	
	NewMaid:GiveTask(child.Control.MouseLeave:Connect(function()

	end))
end

local function RemoveInteractable(child)
	Maid:DoCleaning()
end

Interactables.ChildAdded:Connect(NewInteractable) -- New Interactable
Interactables.ChildRemoved:Connect(RemoveInteractable) -- Remove Interactable

I get this error
Maid:106: invalid argument #1 to ‘pairs’ (table expected, got nil)

I read through this, How to use a Maid class on Roblox to manage state | by James Onnen (Quenty) | Roblox Development | Medium but I’m clearly missing something :confused:

There is also documentation on Maids within Aero framework GitHub website since it’s a shared module.

In your case I believe you need to store the maids that you have given the tasks to in order to tell that Maid that you created to do the cleanup. Currently:

is nil as the NewMaid that you created is localized within the NewInteractable function. You can solve it by storing the NewMaids created within a table like so:

local MaidCafe = {}

local function NewInteractable(child)
	local NewMaid = Maid.new()
	
	NewMaid:GiveTask(child.Control.MouseEnter:Connect(function()
		
	end))
	
	NewMaid:GiveTask(child.Control.MouseLeave:Connect(function()

	end))

        MaidCafe[child] = NewMaid

end

local function RemoveInteractables(child)

	MaidCafe[child]:DoCleaning()

end

Interactables.ChildAdded:Connect(NewInteractable) -- New Interactable
Interactables.ChildRemoved:Connect(RemoveAllInteractables) -- Remove Interactable

If you want to specify which specific Maid clean up then you will need a separate function and find an identifying index for that specific Maid.

Edit: NVM, the child Instance can be an identifying index in this case maybe? IDK what exactly Maids are just the error message in the scenario.

1 Like

Would this cause problems, as MaidCafe table would constantly be adding new things to it? I don’t know much about memory leaks, but wouldn’t this cause problems, as the table would just get larger and larger?

Yeah, the issue with the current method is that it uses an Instance as a key being the child that is added into whatever Instance the Interactables is.

To solve this according to this other thread we got to use weak tables I believe to destroy the key being referenced in the MaidCafe table.

And then after that we got to remove the reference to the Maid Object as well which should be pretty simple since it’s just a table of tasks the Maid has got to do.

Maid constructor
function Maid.new()
	local self = {}

	self._tasks = {}

	return setmetatable(self, Maid)
end

So setting the reference to nil should work like so:

local function RemoveInteractables(child)
	MaidCafe[child]:DoCleaning()
--No more references to the maid object and it's tasks ever again
--within this script I believe
	MaidCafe[child] = nil  
end

Just like how the page of Instance:Destroy() in the dev API reference mentions to fully remove an object.