Value isn't setting through datastore

Hi! So I am trying to make a feature where when a player leaves, the title equipped before the player left is on their avatar automatically when they join back. To do this, I am trying to set the value title to the title above their head, and then setting the value previoustitle to their avatar. Here is what I am using:

function saveData(plrLeaving)
	if not plrLeaving:GetAttribute('DataSuccess') then
		return
	end
	local ownedTools = {}
	for i, tool in pairs(plrLeaving.OwnedTools:GetChildren()) do
		table.insert(ownedTools, tool.Name)
	end
	local ownedTitles = {}
	for i, title in pairs(plrLeaving.OwnedTitles:GetChildren()) do
		table.insert(ownedTitles, title.Name)
	end

	local title;
	pcall(function()
		title = plrLeaving.Character.Head.NameTag.Title.Text
	end)

	local output = {
		Titles = ownedTitles,
		Tools = ownedTools,
		Coins = plrLeaving.leaderstats.Coins.Value,
		Wins = plrLeaving.leaderstats.Wins.Value,
		Skips = plrLeaving.leaderstats.Skips.Value,
		Style = "", -- BE SURE TO SAVE THE STYLE!
		Title = title,
	}

	local success, err = pcall(function()
		ds:SetAsync(plrLeaving.UserId, game.HttpService:JSONEncode(output))
	end)
end

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


	local toolsOwned = {}
	local titlesOwned = {}
	local style = ""
	local title = ""
	local coins = 0
	local wins = 0
	local skips = 0

	local packedData;
	local s, err = pcall(function()
		packedData = ds:GetAsync(plr.UserId)
	end)

	if s then
		plr:SetAttribute('DataSuccess', true)
	else
		print(tostring(err))
	end

	if packedData then
		local s = pcall(function()
			packedData = game.HttpService:JSONDecode(packedData)
		end)
		if typeof(packedData) == 'table' then
			titlesOwned = packedData.Titles or titlesOwned
			toolsOwned = packedData.Tools or toolsOwned
			coins = packedData.Coins or coins
			wins = packedData.Wins or wins
			skips = packedData.Skips or skips
			title = packedData.Title or title
		else
			plr:SetAttribute('DataSuccess', false)
		end
	end
	print(3)

	if not plr:GetAttribute('DataSuccess') then
		-- notify the player that their data did not load successfully.
		local msg = Instance.new('Message')
		msg.Name = '__ALEXSMESSAGE'
		msg.Text = 'Failed to load your data. Please rejoin.'
		msg.Parent = plr:WaitForChild('PlayerGui')
		game.Debris:AddItem(msg, 5)
	end
	print(4)
	local ls = Instance.new("Folder", plr)
	ls.Name = "leaderstats"

	local coinsValue = Instance.new("IntValue", ls)
	coinsValue.Name = "Coins"
	coinsValue.Value = coins

	local winsValue = Instance.new("IntValue", ls)
	winsValue.Name = "Wins"
	winsValue.Value = wins

	local skipsValue = Instance.new("IntValue", ls)
	skipsValue.Name = "Skips"
	skipsValue.Value = skips


	local previoustitle = Instance.new("StringValue", plr)
	previoustitle.Name = "previoustitle"
	previoustitle.Value = title

	local previousstyle = Instance.new("StringValue", plr)
	previousstyle.Name = "previousstyle"
	previousstyle.Value = style
	print(5)
	plr.CharacterAdded:Connect(function(char)
		--Varibles
		local head = char.Head
		local newtext = nametag:Clone() 
		local uppertext = newtext:WaitForChild("Name")
		local lowertext = newtext.Title
		local humanoid = char.Humanoid
		print(6)
		humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None -- use enum instead of a string

		--Main Text
		newtext.Parent = head
		newtext.Adornee = head
		uppertext.Text = plr.Name 

		if plr.previoustitle.Value ~= "" then
			lowertext.Text = plr.previoustitle.Value
		end

		--"If" Statements
		--You can add as many of these as you wish, just change it to the player's name.

	end)

	print(7)
	
	plr.CharacterRemoving:Connect(function()
		title = plr.Character.Head.Nametag.Title.Text
		
	end)





	local ownedFolder2 = Instance.new("Folder", plr)
	ownedFolder2.Name = "OwnedTools"

	local ownedFolder3 = Instance.new("Folder", plr)
	ownedFolder3.Name = "OwnedTitles"

	for i, owned in pairs(toolsOwned) do

		if tools:FindFirstChild(owned) then

			tools[owned]:Clone().Parent = ownedFolder2
		end
	end

	for i, owned in pairs(titlesOwned) do

		if titles:FindFirstChild(owned) then

			titles[owned]:Clone().Parent = ownedFolder3
		end
	end

end)


game.Players.PlayerRemoving:Connect(saveData)

When the player leaves, it uses this event and saves title to the top of the character’s head.

plr.CharacterRemoving:Connect(function()
		title = plr.Character.Head.Nametag.Title.Text
		
	end)

And then it saves it:

local title;
	pcall(function()
		title = plrLeaving.Character.Head.NameTag.Title.Text
	end)

When the player joins back it loads it:

if packedData then
		local s = pcall(function()
			packedData = game.HttpService:JSONDecode(packedData)
		end)
		if typeof(packedData) == 'table' then
			titlesOwned = packedData.Titles or titlesOwned
			toolsOwned = packedData.Tools or toolsOwned
			coins = packedData.Coins or coins
			wins = packedData.Wins or wins
			skips = packedData.Skips or skips
			title = packedData.Title or title
		else
			plr:SetAttribute('DataSuccess', false)
		end
	end
	print(3)

But, it is still not working. Can anybody help me with this?

I think the main problem has to do with this line here:

local title;
	pcall(function()
		title = plrLeaving.Character.Head.NameTag.Title.Text
	end)

Its setting title to that when it already is setting it to that during this event.

plr.CharacterRemoving:Connect(function()
		title = plr.Character.Head.Nametag.Title.Text
		
	end)

But I don’t know what to change it to.

I have tried getting rid of both instances but none of them seem to work but I still believe the underlying problem has to do with previoustitle not being set in the first place.