Best way to use datastore for a menu GUI

Hello, I’m trying to use ProfileService to save a menu’s values and I wanna know what’s the best way of doing it, I tried to load the data once the player joins but it checks if the data exists before the ProfileService’s MenuDataHandler I made can save the data.

Here’s the MenuDataHandler script:

local ProfileService = require(game.ReplicatedStorage:FindFirstChild("ProfileService"))
local Players = game:GetService("Players")

local scriptdebug = true

local function dprint(msg)
	if scriptdebug == true then
		warn(msg)
	end
end

local ProfileStore = ProfileService.GetProfileStore(
	"Player",
	{
		ResetDelay = 5;
	}
)

local Profiles = {}

local function onPlayerAdded(player)
	dprint("a player has joined")
	
	local profile = ProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)
	
	if profile then
		profile:ListenToRelease(function()
			Profiles[player] = nil
			player:Kick()
		end)
		
		if player:IsDescendantOf(Players) then
			Profiles[player] = profile
			
			dprint("a player's profile has been saved")
		else
			profile:Release()
		end
	else
		player:Kick()
	end
end

local function onPlayerRemoving(player)
	local profile = Profiles[player]
	
	if profile then
		profile:Release()
	end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

-- In case Players have joined the server earlier than this script ran:
for _, player in ipairs(Players:GetPlayers()) do
	task.spawn(onPlayerAdded, player)
end

local DataManager = {}

function DataManager:Get(player)
	local profile = Profiles[player]
	
	if profile then
		dprint("a player's Profile data loaded")
		
		return profile
	end
end

return DataManager

And here’s the script that tries loading and applying the data to the values:

local MessagingService = game:GetService("MessagingService")
local DataManager = require(game.ReplicatedStorage.MenuDataManager)
local Players = game:GetService("Players")

game.Players.PlayerAdded:Connect(function(player)
	local Menu = script.Menu:Clone()

	player.CharacterAdded:Connect(function()
		if not player.PlayerGui:FindFirstChild("Menu") then
			Menu.Parent = player.PlayerGui
			print("[Menu] Inserted!")
		end
	end)
end)

local function onPlayerAdded(player)
	local gui = player.PlayerGui:WaitForChild("Menu")

	if player then
		local data = DataManager:Get(player)

		if data then
			for i, v in pairs(gui.Main.TabsFrame.Tabs:GetDescendants()) do
				if v:IsA("ValueBase") then
					v.Value = data.v.Value.Parent.Name
					print(player.. "'s menu data loaded")

					v:GetPropertyChangedSignal("Value"):Connect(function()
						data.v.Value.Parent.Name = v.Value
						print(player.. "'s menu data saved")
					end)
				end
			end
		else
			print("Whoops, something went wrong.")
		end
	end
end

game.Players.PlayerAdded:Connect(onPlayerAdded)

-- In case Players have joined the server earlier than this script ran:
for _, player in ipairs(Players:GetPlayers()) do
	task.spawn(onPlayerAdded, player)
end