My Catalog Module Fixing

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I want to basically make a catalog module that uses avatareditorservice

  2. What is the issue? The Issue is that I’m trying to make it delay or time so it goes faster.

  3. What solutions have you tried so far? No. I Haven’t I tried looking for solutions but, no results

Can anyone help me? because it is an issue (also making the table fix there things)

Code:


--Services
local AvatarEditorService = game:GetService("AvatarEditorService")
local RunService = game:GetService("RunService")
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")

local catalog = {}
catalog.assetFolders = {}
catalog.creatorName = ""
catalog.searchKeyword = ""
catalog.dataItems = {
	-- Accessories
	["BackAccessory"] = {};
	["FaceAccessory"] = {};
	["FrontAccessory"] ={};
	["HairAccessory"] = {};
	["Hat"] = {};
	["NeckAccessory"] = {};
	["ShoulderAccessory"] = {};
	["WaistAccessory"] = {};

	-- Animations
	["ClimbAnimation"] = {};
	["FallAnimation"] = {};
	["IdleAnimation"] = {};
	["JumpAnimation"] = {};
	["RunAnimation"] = {};
	["SwimAnimation"] = {};
	["WalkAnimation"] = {};

	-- Body Parts
	["Face"] = {};
	["Head"] = {};
	["LeftArm"] = {};
	["LeftLeg"] = {};
	["RightArm"] = {};
	["RightLeg"] = {};
	["Torso"] = {};

	-- Clothes
	["TShirt"] = {};
	["Pants"] = {};
	["Shirt"] = {};
}

-- roblox api is broken currently and gives camelCase
local function tableToPascalCaseKeys(oldTable)
	local newTable = {}
	for k, v in pairs(oldTable) do
		local newKey = k
		if typeof(k) == "string" then
			newKey = string.upper(string.sub(k, 1, 1)) .. string.sub(k, 2)
		end
		local newValue = v
		if typeof(v) == "table" then
			newValue = tableToPascalCaseKeys(v)
		end
		newTable[newKey] = newValue
	end
	return newTable
end

function iterPageItems(pages)
	return coroutine.wrap(function()
		local pagenum = 1
		while true do
			for _, item in ipairs(pages:GetCurrentPage()) do
				coroutine.yield(item, pagenum)
			end
			if pages.IsFinished then
				break
			end
			pages:AdvanceToNextPageAsync()
			pagenum = pagenum + 1
		end
	end)
end

-- Reformat pages as tables
--local function pagesToTable(pages)
--	local items = {}
--	while true do
--		table.insert(items, pages:GetCurrentPage())
--		if pages.IsFinished then
--			break
--		end
--		pages:AdvanceToNextPageAsync()
--	end
--	return items
--end

--local function iterPageItems(pages)
--	local contents = pagesToTable(pages)
--	-- Track the current page number starting at 1
--	local pageNum = 1
--	-- Get last page number so we don't iterate over it
--	local lastPageNum = #contents

--	-- for resumes this coroutine until there's nothing to go through
--	return coroutine.wrap(function()
--		-- Loop until page number is greater than last page number
--		while pageNum <= lastPageNum do
--			-- Go through all the entries of the current page
--			for _, item in ipairs(contents[pageNum]) do
--				-- Pause loop to let developer handle entry and page number
--				coroutine.yield(item, pageNum)
--			end
--			pageNum += 1
--		end
--	end)
--end

local function retry(functionToRetry, timeToWait, max): (boolean, any)
	if not timeToWait then timeToWait = 2 end
	if not max then max = math.huge end

	local success, returnValue
	local attempts = 0

	repeat
		success, returnValue = pcall(functionToRetry)
		if not success then
			warn(returnValue)
			local timeWaited = 0
			repeat
				timeWaited += RunService.Heartbeat:Wait()
			until timeWaited >= timeToWait
		end
		attempts += 1
	until success == true or attempts == max

	return success, returnValue
end

function catalog:generateCatalog(options: { assetTypes: { Enum.AvatarAssetType } })
	local params = CatalogSearchParams.new()
	params.AssetTypes = options.assetTypes
	params.SearchKeyword = self.searchKeyword
	params.CreatorName = self.creatorName
	params.Limit = 10

	local excludedAssetTypes = {Enum.AvatarAssetType.ClimbAnimation, Enum.AvatarAssetType.FallAnimation, Enum.AvatarAssetType.IdleAnimation, Enum.AvatarAssetType.JumpAnimation, Enum.AvatarAssetType.RunAnimation, Enum.AvatarAssetType.SwimAnimation, Enum.AvatarAssetType.WalkAnimation}
	local itemAssetType
	
	for _, assetType in pairs(options.assetTypes) do
		if table.find(excludedAssetTypes, assetType) then
			params.CreatorName = "Roblox"
			params.SearchKeyword = ""
			params.IncludeOffSale = true
		else
			params.AssetTypes = {assetType}
		end
		itemAssetType = assetType.Name
	end
	
	local choosenItem
	local timeToWait = 3
	local Assets = self.dataItems[itemAssetType]
	local Amount = script:GetAttribute("maxItems")
	
	if Amount > #Assets or Amount == 0 then
		local _, resultPages: CatalogPages = retry(function()
			return AvatarEditorService:SearchCatalog(params)
		end, 3, Amount)

		while Amount > #Assets or Amount == 0 do
			local currentPage = resultPages:GetCurrentPage()
			for _, itemData in pairs(currentPage) do
				local folders = catalog:setUpFolders(itemData.AssetType)
				if script:GetAttribute("showFolders") then
					for i=1, Amount do
						local item = Instance.new("NumberValue", script.Assets:FindFirstChild(itemData.AssetType))
						item.Name = itemData.Name
						item.Value = itemData.Id


						local Childs = script.Assets:FindFirstChild(itemData.AssetType):GetChildren() --You can edit this for whatever fits for you.
						local StringValueNames = {} --A table just to put the original string value names in.
						for i,v in ipairs(Childs) do
							if v:IsA("NumberValue") then
								if table.find(StringValueNames,v.Name,1) == nil then
									table.insert(StringValueNames,#StringValueNames+1,v.Name) --Inserts a new stringvalue name because there wasn't one in the table.
								else
									v:Destroy() --Destroys the string value because another stringvalue with the same name exist.
								end
							end
						end
						break
					end
				end
				table.insert(self.dataItems[itemAssetType], itemData.Id)
				if #self.dataItems[itemAssetType] == script:GetAttribute("maxItems") then
					break
				end
			end
			if not resultPages.IsFinished then
				xpcall(resultPages.AdvanceToNextPageAsync, function() end, resultPages)
			end
		end	
	end
	
	return self.dataItems
end

function catalog:setUpFolders(data)
	retry(function()
		if not script.Assets:FindFirstChild(data) then
			local Folder = Instance.new("Folder", script.Assets)	
			Folder.Name = data
			table.insert(self.assetFolders, Folder)
		end
	end)

	return self.assetFolders
end

return catalog