Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to load table of data as objects?

I have a data saving script and I would like to store all the objects inside the folder and save them but I do not know how I would load the data. Saving works perfectly fine but I do not know how to take the table of data and make new objects based on that.

Here is my code:

local Players = game:GetService("Players")

-- DataStores

local DSService = game:GetService("DataStoreService")
local data = DSService:GetDataStore("saveData")

local function PlayerJoined(player)
	
	local key = player.UserId
	local dataFolder = Instance.new("Folder", player)
	dataFolder.Name = "Data"
	
	local onMenu = Instance.new("BoolValue", dataFolder)
	onMenu.Name = "onMenu"
	onMenu.Value = true
	
	if data:GetAsync(key) == nil then
		local Inventory = Instance.new("Folder", dataFolder)
		Inventory.Name = "Inventory"
	else 
	
		local loadedData = data:GetAsync(key)
		
		-- load data here
		
	end
end

local function PlayerRemoving(player)
	
	local key = player.UserId

	local tab = {}

	for _, v in ipairs(player:WaitForChild("Data"):GetDescendants()) do
		
		if (not v:IsA("Folder")) then
			table.insert(tab,{ v.Name, tostring(v.Value), v.ClassName, tostring(v.Parent)})
		else
			table.insert(tab,{ v.Name, v.ClassName, tostring(v.Parent)})
		end
		
	end
		data:SetAsync(key, tab)
		print(tab)
end


Players.PlayerAdded:Connect(PlayerJoined)
Players.PlayerRemoving:Connect(PlayerRemoving)

1 answer

I'd personally set indexes to the corresponding values so they are easier to find when loading them. Such as:

local function PlayerRemoving(player)

	local key = player.UserId

	local tab = {}

	for _, v in ipairs(player:WaitForChild("Data"):GetDescendants()) do

		if (not v:IsA("Folder")) then
			table.insert(tab,{Name = v.Name, Value = tostring(v.Value), ClassName = v.ClassName, Parent = tostring(v.Parent)})
		else
			table.insert(tab,{Name = v.Name, ClassName = v.ClassName, Parent = tostring(v.Parent)})
		end
	end
	data:SetAsync(key, tab)
	print(tab)
end

From there, since you now have indexes that correspond to their values, it'll be much easier to find and load them.

local function newInstance(instance, properties)

	instance.Name = properties.Name
	
	if properties.Value then
		instance.Value = properties.Value
	end
	return instance
end

local function PlayerJoined(player)

	local key = player.UserId
	local dataFolder = Instance.new("Folder", player)
	dataFolder.Name = "Data"

	local onMenu = Instance.new("BoolValue", dataFolder)
	onMenu.Name = "onMenu"
	onMenu.Value = true

	if data:GetAsync(key) == nil then
		local Inventory = Instance.new("Folder", dataFolder)
		Inventory.Name = "Inventory"
	else 
		local loadedData = data:GetAsync(key)

		if loadedData then
			-- load data here
			for index, properties in pairs(loadedData) do
				local instance = newInstance(Instance.new(properties.ClassName), properties)

				local parent = player:FindFirstChild(properties.Parent, true)
				instance.Parent = parent
			end
		end
	end
end

You should also be wrapping Async in a pcall function, as Async can fail and error.

5 comments

0

works very well but for some reason it will not set the value correctly.

0

Hmm.. I can't see anything in the script that would be causing that problem. Try printing the properties table and see if it has the correct value for the instance being loaded.

0

ive tried multiple prints and everything seems fine but it keeps setting it to true.

0

figured it out, its because properties.Value is a string and you cant set instance.Value to a string because its a bool value

0

Glad you figured it out.

This discussion is preserved as it was. New answers, comments, and votes are closed.