Save multiple values that are descendants of players gui

Hello, i have this datastore code that supposed to do what the post title says, but for some reason when i leave i get this message in the output

DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests.Key = 3707553335

Theres alot of value in the gui, why is it not saving?

local datastore = game:GetService("DataStoreService")
local Gamedata = datastore:GetGlobalDataStore("SlotData")




function saveData(Player,plrStats)

	local DataToSave = {}


	print("Saving Slot Data...")
	for i, data in pairs(plrStats:GetChildren()) do
		DataToSave[i] = data.Value
	end

	Gamedata:SetAsync(Player.UserId,DataToSave)
	print("Slots Saved")



end

game.Players.PlayerAdded:Connect(function(Player)
	


	local plrsaves
	pcall (function()
		plrsaves = Gamedata:GetAsync(Player.UserId)

	end)
	if plrsaves then
		--If player has data
		warn("Player has Slot Data!")
		for i, data in pairs(Player.PlayerGui.HUD.MenuGui:GetDescendants()) do

			data.Value = plrsaves[i]

			print (data.Name,":",data.Value)
		end

	else

		--if player doenst have data
		warn("Player has No Slot Data.")
		for i, data in pairs(Player.PlayerGui.HUD.MenuGui:GetDescendants()) do

			print (data.Name,":",data.Value)

		end	
	end
	


end)



game.Players.PlayerRemoving:Connect(function(Player)
	local PlrStats = Player:WaitForChild("PlrStats")
	saveData(Player,PlrStats)

end)

Edit: I figured out some of it but now it wont save when leaving because it cant find the player playergui

The issue is that you have not waited for the PlayerGui to be created before trying to get its descendants. You should add a waitForChild to the Player object and then try to get the descendants of PlayerGui.

local PlayerGui = Player:WaitForChild("PlayerGui")

for i, data in pairs(PlayerGui.HUD.MenuGui:GetDescendants()) do
	data.Value = plrsaves[i]

	print (data.Name,":",data.Value)
end

Well when joining it successfully gets the values, its just when leaving it doesnt, i know it does when joining because i have it print out the values, so its the leaving part, it doesnt find the playergui

If you are sure that the PlayerGui is there when the player leaves, then it could be that the DataStore request is taking too long, and the player leaves before the DataStore request is processed. Try using DataStoreService:SetGlobalAsync instead of DataStoreService:SetAsync to ensure that the DataStore request is processed immediately.

How can i fix that is there any way i could just rewrite it or can you tell me how so it works, because i have no idea how to fix it

And also this didnt work, it still couldnt find playergui

Any way i could make it save every 10 seconds while in game? instead of when the player leaves?

local datastore = game:GetService("DataStoreService")
local Gamedata = datastore:GetGlobalDataStore("SlotData")




function saveData(Player,plrStats)

	local DataToSave = {}

	
	print("Saving Slot Data...")
	for i, data in pairs(Player.PlayerGui.HUD.MenuGui:GetDescendants()) do
		if data:IsA("BoolValue") then
			DataToSave[i] = data.Value
		end
		
	end

	Gamedata:SetAsync(Player.UserId,DataToSave)
	print("Slots Saved")



end

game.Players.PlayerAdded:Connect(function(Player)
	
	local PlayerGui = Player:WaitForChild("PlayerGui")
	local HUD = PlayerGui:WaitForChild("HUD")
	local plrsaves
	pcall (function()
		plrsaves = Gamedata:GetAsync(Player.UserId)

	end)
	if plrsaves then
		--If player has data
		warn("Player has Slot Data!")
		for i, data in pairs(HUD.MenuGui:GetDescendants()) do
			if data:IsA("BoolValue") then
				data.Value = plrsaves[i]

				print (data.Name,":",data.Value)
			end

		
		end

	else

		--if player doenst have data
		warn("Player has No Slot Data.")
		for i, data in pairs(HUD.MenuGui:GetDescendants()) do
			if data:IsA("BoolValue") then
				print (data.Name,":",data.Value)
			end

			

		end	
	end
	while wait(10) do
		print("saved")
		local MenuStats = Player
		saveData(Player,MenuStats)
	end
	

end)

I got some of it to work but when joining back the value doesnt change, it says it saves though

It’s possible that using DataStoreService:SetGlobalAsync instead of DataStoreService:SetAsync could help resolve the issue you’re experiencing.

Here’s an example of how you could modify your code to use SetGlobalAsync:

local DataStoreService = game:GetService("DataStoreService")
local PlayersDataStore = DataStoreService:GetGlobalDataStore("PlayersDataStore")

-- Other code

PlayersDataStore:SetGlobalAsync("PlayerStats", playerStats)

SetGlobalAsync is similar to SetAsync, but it has a higher priority and is processed immediately. This can be useful if you need to ensure that data is saved in a timely manner, as it can help prevent issues like the one you described.

I hope this helps! Let me know if you have any other questions.

It looks like you’re using a while loop to save the data every 10 seconds. While this can be a good way to ensure that the data is saved frequently, it may not be the most efficient approach. You may want to consider using a different method to save the data, such as using a BindableEvent or a RemoteEvent to trigger the save whenever the data needs to be updated.

Here’s an example of how you could use a BindableEvent to save the data whenever it’s changed:

local datastore = game:GetService("DataStoreService")
local Gamedata = datastore:GetGlobalDataStore("SlotData")

local dataChangedEvent = Instance.new("BindableEvent")

function saveData(Player)
	local DataToSave = {}

	print("Saving Slot Data...")
	for i, data in pairs(Player.PlayerGui.HUD.MenuGui:GetDescendants()) do
		if data:IsA("BoolValue") then
			DataToSave[i] = data.Value
		end
	end

	Gamedata:SetAsync(Player.UserId, DataToSave)
	print("Slots Saved")
end

game.Players.PlayerAdded:Connect(function(Player)
	local PlayerGui = Player:WaitForChild("PlayerGui")
	local HUD = PlayerGui:WaitForChild("HUD")

	local plrsaves
	pcall(function()
		plrsaves = Gamedata:GetAsync(Player.UserId)
	end)

	if plrsaves then
		-- If player has data
		warn("Player has Slot Data!")
		for i, data in pairs(HUD.MenuGui:GetDescendants()) do
			if data:IsA("BoolValue") then
				data.Value = plrsaves[i]
				print(data.Name, ":", data.Value)
			end
		end
	else
		-- If player doesn't have data
		warn("Player has No Slot Data.")
		for i, data in pairs(HUD.MenuGui:GetDescendants()) do
			if data:IsA("BoolValue") then
				print(data.Name, ":", data.Value)
			end
		end
	end

	-- Save the data whenever it's changed
	dataChangedEvent.Event:Connect(function()
		saveData(Player)
	end)
end)

With this approach, you can trigger the save by calling the Fire() method of the BindableEvent whenever the data is changed. For example:

-- Update the data
data.Value = true

-- Trigger the save
dataChangedEvent:Fire()

I hope this helps! Let me know if you have any other questions or if you’d like further clarification.