Ui Change Does Not Update

hello! i have a module script and a server script that taked with setting up unlocked and locked items. my problem is when i go to unlock a item it seems that the ui does not update, and only and only updates when i rejoin the game. im wondering why this is and how i can fix it?

– module script

	local unlockedModule = {}
	
	local replicatedStorage = game:GetService("ReplicatedStorage")
	local datastoreService = game:GetService("DataStoreService")
	local unlockedData = datastoreService:GetDataStore("UISAD")

	unlockedModule.itemStats = {
		["apple"] = {
			locked = true,
			image = "rbxassetid://5673482401"
		},
		["gold bar"] = {
			locked = true,
			image = "rbxassetid://18336886764"
		},
		["painting"] = {
			locked = true,
			image = "rbxassetid://18367945834"
		},
		["stolen bank info"] = {
			locked = true,
			image = "rbxassetid://18336886764"
		},
		["flower pot"] = {
			locked = true,
			image = "rbxassetid://18336886764"
		},
	}

	function unlockedModule:saveData(player, itemStats)
		local success, errorMessage = pcall(function()
			unlockedData:SetAsync(player.UserId .. "-unlockedStats", itemStats)
		end)

		if not success then
			warn("Failed to save unlocked items " .. errorMessage)
		end
	end

	function unlockedModule:loadData(player)
		local success, unlockedStatsTable = pcall(function()
			return unlockedData:GetAsync(player.UserId .. "-unlockedStats")
		end)

		if success and unlockedStatsTable then
			return unlockedStatsTable
		else
			if not success then
				warn("Failed to load weapon damage: " .. unlockedStatsTable)
			end
			return unlockedModule.itemStats
		end
	end

function unlockedModule:getItemAttribute(player, name, attribute)
	local unlockedItemStats = self:loadData(player)

	if unlockedItemStats[name] then
		return unlockedItemStats[name][attribute] or unlockedModule.itemStats[name][attribute]
	else
		return unlockedModule.itemStats[name][attribute]
	end
end

	function unlockedModule:updateItemAttribute(player, name, attribute, value)
		local unlockedItemStats = self:loadData(player)

		if not unlockedItemStats[name] then
			unlockedItemStats[name] = {}
		end

		unlockedItemStats[name][attribute] = value

		self:saveData(player, unlockedItemStats)
	end

	unlockedModule.lockedItems = {}
	unlockedModule.unlockedItems = {}

	function unlockedModule:getUnlockedItems(player)
		local itemStatsTable = self:loadData(player)
		self.unlockedItems = {} 

		for name, attributes in pairs(itemStatsTable) do
			if attributes["locked"] == false then
				table.insert(self.unlockedItems, name)
				print("unlocked: " ..name)
			end
		end
		
		return self.unlockedItems

	end

	function unlockedModule:getLockedItems(player)
		local itemStatsTable = self:loadData(player)
		self.lockedItems = {} -- Reset table

		for name, attributes in pairs(itemStatsTable) do
			if attributes["locked"] == true then
				table.insert(self.lockedItems, name)
				print("locked: " .. name)
			end
		end

		return self.lockedItems
	end
	
local function printTable(t, indent)
	indent = indent or 0
	local indentString = string.rep("  ", indent)

	for key, value in pairs(t) do
		if type(value) == "table" then
			print(indentString .. key .. ":")
			printTable(value, indent + 1)
		else
			print(indentString .. key .. ": " .. tostring(value))
		end
	end
end


	function unlockedModule:unlockItem(player, itemName)
		local itemStatsTable = self:loadData(player)
		local unlockRemoteEvent = replicatedStorage:WaitForChild("mechanics"):FindFirstChild("Ui"):FindFirstChild("itemIndex"):FindFirstChild("unlockEvent")
		
		if itemStatsTable[itemName]["locked"] == false then return end
		
		if itemStatsTable[itemName]["locked"] == true then
			
		local lockedTable = self:getLockedItems(player)
		local unlockedTable = self:getUnlockedItems(player)
		
		for i, item in ipairs(lockedTable) do
			if item == itemName then
				table.remove(lockedTable, i)
				table.insert(unlockedTable, i)
				self:updateItemAttribute(player, itemName, "locked", false)
				break
			end
		end
		
		self:saveData(player, itemStatsTable)
			
			
		repeat task.wait() until table.find(unlockedTable, itemName)
			

		print("firedddd")
			
			unlockRemoteEvent:FireClient(player)
			
			printTable(itemStatsTable)
			
		end
	end


return unlockedModule

– server script

local replicatedStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local itemStats = require(replicatedStorage:WaitForChild("server"):FindFirstChild("ItemsWorth"))


players.PlayerAdded:Connect(function(player)
	local playerStats = player:FindFirstChild("playerStats")
	local otherStats = player:FindFirstChild("otherStats")

	local function waitForChild(parent, childName, timeout)
		local startTime = tick()
		while not parent:FindFirstChild(childName) do
			if timeout and (tick() - startTime) >= timeout then
				warn(childName .. " not found within timeout")
				return nil
			end
			task.wait(0.1)
		end
		return parent:FindFirstChild(childName)
	end

	playerStats = waitForChild(player, "playerStats", 10)
	otherStats = waitForChild(player, "otherStats", 10)

	if not playerStats or not otherStats then
		warn("playerStats or otherStats not found within the given timeout.")
		return
	end
	
	local playerGui = player:WaitForChild("PlayerGui")
	local scrollingFrame = playerGui:WaitForChild("uiStats"):WaitForChild("itemIndexFrame"):WaitForChild("ScrollingFrame")

	
	local unlockedItemsModule = require(replicatedStorage:WaitForChild("client"):WaitForChild("unlockedIndexModule"))
	
	local playerlevel = playerStats:WaitForChild("level")


	local unlockRemoteEvent = replicatedStorage:WaitForChild("mechanics"):FindFirstChild("Ui"):FindFirstChild("itemIndex"):FindFirstChild("unlockEvent")
	
	local function updateUi()
		

		local unlockedItemsTable = unlockedItemsModule:getUnlockedItems(player)
		
		local lockedItemsTable = unlockedItemsModule:getLockedItems(player)
		
		for _, child in pairs(scrollingFrame:GetChildren())  do
			if child:IsA("TextButton") then
				child:Destroy()
			end
		end
		
		print("cleared")
		
		for _, weaponName in ipairs(unlockedItemsTable) do
			local template = replicatedStorage:WaitForChild("mechanics"):FindFirstChild("Ui"):FindFirstChild("itemIndex"):WaitForChild("indexTemplate"):Clone()
			
			template.LayoutOrder = 0

			template.indexImage.Image = unlockedItemsModule:getItemAttribute(player, weaponName, "image")
			template.indextText.Text = weaponName

			template.lockedFrame:Destroy()

			template.Name = weaponName
			

			template.Parent = scrollingFrame
		end
		
		for _, weaponName in ipairs(lockedItemsTable) do
			local template = replicatedStorage:WaitForChild("mechanics"):FindFirstChild("Ui"):FindFirstChild("itemIndex"):WaitForChild("indexTemplate"):Clone()
			template.LayoutOrder = 1

			template.indexImage.Image = unlockedItemsModule:getItemAttribute(player, weaponName, "image")
			template.indextText.Text = weaponName

			template.lockedFrame.Visible = true

			template.Name = weaponName
			
			template.Parent = scrollingFrame
		end
	end
	
	updateUi()
	
	unlockRemoteEvent.OnServerEvent:Connect(function(player)
		updateUi()
	end)

end)

Maybe you should update UI in LocalScript

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.