Items not being loaded 100% of the time

Local Script that goes through a folder (inside RepStorage, contains face images) and creates a button for each face. It always creates the ImageButton and the 2 TextLabels, and the Image loads, but the TextLabels text sometimes doesn’t load properly and just stays ‘Label’ It does print ‘firing’ however, so the checkItem Event is being fired. I also try to store if they have an item inside playerItems, so the LocalScript doesn’t have to keep going to the server to see if they have the item. So it should insert an item into playerItems when a player joins and when they buy a new item.

local playerItems = {}

function check(item)
print('firing')
    	checkItem:FireServer('Face', item)
    end

checkItem.OnClientEvent:Connect(function(hasItem, item)
	local inFolderItem = faces:FindFirstChild(item)
	print('3')
	if inFolderItem then
		print('4')
		local button = frame:FindFirstChild(inFolderItem.Priority.Value)
		if button then
			print('5')
			if hasItem then
				print('6')
				for _, v in pairs(playerItems) do
					print('7')
					if v ~= item then
						print('8')
						table.insert(playerItems, item)
					end
				end
				button:FindFirstChild('TopLabel').Text = 'Equip'
				button.TopLabel.BackgroundColor3 = Color3.fromRGB(255, 182, 79)
				if button:FindFirstChild('CostLabel') then
					button.CostLabel:Destroy()
				end
			else
				button:FindFirstChild('TopLabel').Text = 'Buy'
				button.TopLabel.BackgroundColor3 = Color3.fromRGB(85, 255, 127)
				button.CostLabel.Text = '$' .. inFolderItem.Cost.Value
			end
		end
	end
end)

function buttonSelected(button)
	selectSound:Play()
	button.TopLabel:TweenPosition(UDim2.new(0, 0, 0, 0), 'Out', 'Quint', 0.5, true)
end

function buttonUnselected(button)
	button.TopLabel:TweenPosition(UDim2.new(0, 0, -0.2, 0), 'Out', 'Quint', 0.5, true)
end

for i, v in pairs(faces:GetChildren()) do
	--[[ Check for the new item ]]--
	check(v.Name)

	--[[ ImageButton ]]--
	local button = Instance.new('ImageButton', frame)
	button.AutoButtonColor = false
	button.BackgroundColor3 = Color3.fromRGB(150, 150, 150)
	button.BorderSizePixel = 0
	button.Name = v.Priority.Value
	button.ZIndex = 3
	button.ClipsDescendants = true
	button.Image = 'rbxassetid://' .. v.ImageID.Value
	
	--[[ TopLabel ]]--
	local topLabel = Instance.new('TextLabel', button)
	topLabel.BorderSizePixel = 0
	topLabel.Name = 'TopLabel'
	topLabel.Position = UDim2.new(0, 0, -0.2, 0)
	topLabel.Size = UDim2.new(1, 0, 0.2, 0)
	topLabel.ZIndex = 3
	topLabel.Font = 'SourceSansBold'
	topLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
	topLabel.TextScaled = true
	topLabel.TextStrokeTransparency = 0
	
	--[[ CostLabel ]]--
	local costLabel = Instance.new('TextLabel', button)
	costLabel.AnchorPoint = Vector2.new(0, 1)
	costLabel.BackgroundTransparency = 1
	costLabel.BorderSizePixel = 0
	costLabel.Name = 'CostLabel'
	costLabel.Position = UDim2.new(0, 0, 1, 0)
	costLabel.Size = UDim2.new(1, 0, 0.2, 0)
	costLabel.ZIndex = 3
	costLabel.Font = 'SourceSansBold'
	costLabel.TextColor3 = Color3.fromRGB(85, 255, 127)
	costLabel.TextScaled = true
	costLabel.TextStrokeTransparency = 0
end

Server Script (only the function that’s used is below) Inside the script, it has a print(itemType) which doesn’t get printed

itemsData = {}

    function check(player, itemType, item)
    	for i, v in pairs(itemsData) do
    		if v[1] == player.UserId then
    			print(itemType)
    			local hasItem = false
    			if itemType == 'Gun' then
    				for _, table in pairs(v[2]) do
    					if table == item then
    						hasItem = true
    					end
    				end
    			elseif itemType == 'Hat' then
    				for _, table in pairs(v[3]) do
    					if table == item then
    						hasItem = true
    					end
    				end
    			elseif itemType == 'Face' then
    				print('lala')
    				for _, table in pairs(v[4]) do
    					print('41213')
    					if table == item then
    						hasItem = true
    					end
    				end
    			elseif itemType == 'Shirt' then
    				for _, table in pairs(v[5]) do
    					if table == item then
    						hasItem = true
    					end
    				end
    			elseif itemType == 'Pant' then
    				for _, table in pairs(v[6]) do
    					if table == item then
    						hasItem = true
    					end
    				end
    			end
    			checkItem:FireClient(player, hasItem, item)
    			return hasItem
    		end
    	end
    end

    checkItem.OnServerEvent:Connect(check) 

    game.Players.PlayerAdded:Connect(function(player)
    	local playerItems = {player.UserId, {'Starter'}, {'Shaggy'}, {'Joyful Smile'}, {'Motorcycle Shirt'}, {'Paintball Pants'}}
    	
    	local loadedGuns = itemsDataStore:GetAsync(player.UserId .. '-guns')
    	local loadedHats = itemsDataStore:GetAsync(player.UserId .. '-hats')
    	local loadedFaces = itemsDataStore:GetAsync(player.UserId .. '-faces')
    	local loadedShirts = itemsDataStore:GetAsync(player.UserId .. '-shirts')
    	local loadedPants = itemsDataStore:GetAsync(player.UserId .. '-pants')
    	
    	if loadedGuns ~= nil then
    		playerItems[2] = loadedGuns
    	end
    	if loadedHats ~= nil then
    		playerItems[3] = loadedHats
    	end
    	if loadedFaces ~= nil then
    		playerItems[4] = loadedFaces
    	end
    	if loadedShirts ~= nil then
    		playerItems[5] = loadedShirts
    	end
    	if loadedPants ~= nil then
    		playerItems[6] = loadedPants
    	end
    	table.insert(itemsData, playerItems)
    end)

It works which is confusing, it just doesn’t work all the time, so it’s hard to really know why? I don’t know if maybe it’s being fired too many times and is overiding or what

EDIT or maybe I’m doing this the wrong way? I don’t know of an easier way to do this.
I also believe I found where the code is stopping. It stops on line 2 of the Server Script (I put a print on line 3 and it doesn’t print, but prints when I have something above line 2)

EDIT2 I believe I found what the problem is. The LocalScript is sometimes firing the checkItem event before the items are being added to itemsData. I put prints there and on the times it worked, it printed that the player had the items put in their data before the event was fired and when it didn’t work it fired the event before the items had been loaded by the datastore. Is there a way to have the checkItem event wait until Datastores have been loaded?

Is there a way to have the checkItem event wait until Datastores have been loaded?

Create a remote function called DatastoreLoaded or something like that and have the function attached to the checkItem event either yield until it’s true or repeatedly call the function until it returns true.