How can I save everything in a folder? (In the datastores)

I’ve seen the answer before but I cannot find it or it was deleted.

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

  1. What do you want to achieve? Keep it simple and clear!
    I want to loop through a folder and save every name and the value.

  2. What is the issue?
    I don’t know how to do it and I cannot find my old code.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I looked on the developer hub and other Roblox scripting websites for my answer.

Sorry if I’m asking for an entire script, I just cannot find this. I know how to use the datastore and everything but I can’t find this.
Thanks,
AtScripterBoy.

4 Likes

You can simply create an array to save by iterating through the leaderstats folder like so:

local Data = {}

for _, ValueObject in pairs(leaderstats:GetChildren()) do
    Data[ValueObject.Name] = ValueObject.Value
end

This is a bit of a nitpick, but that’s not an array. An array uses numeric keys.

3 Likes

I can’t see how your comment is contributive to the current topic but let me answer with a quote from wikipedia:

In computer science, an array data structure , or simply an array , is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key .

I think I found the answer.

local dss = game:GetService('DataStoreService'):GetDataStore('PlayerData') --retrieving a DataStore by a random name

game.Players.ChildRemoved:Connect(function(player)
    local tbl = {}
    local success, message = pcall(function() --wrapping the saving part in a pcall
        for _,v in pairs(the folder) do
            tbl[#tbl+1] = v.Name
        end
        dss:SetAsync(player.UserId, tbl) -- saving the data
    end)
    if success then
         print("Saved "..player.Name.."'s data")
    else
        print('Failed to save data: '..message)
    end
end)

To get the data

game.Players.ChildAdded:Connect(function(player)
    local data = dss:GetAsync(player.UserId) or {}
    local folder = Instance.new('Folder')
    folder.Name = 'Inventory'
    folder.Parent = player

    for _, v in pairs(data) do
        local value = Instance.new('StringValue') --your type of value here
        value.Name = v
        value.Parent = the folder
    end
end)
1 Like

I that only saves the name not the value.

It seems to me that it only saves the name of the value, and not the actual value itself. You might want to change that.

I found a way to fix that.

(I need 30 characters)

Lua tables are implemented as associative arrays. For the sake of convenience, we call anything with numerical indices an array and anything with non-numerical indices a dictionary. What you’re using is a dictionary, not an array, by Roblox standards.

Arrays are treated in the form of elements, and dictionaries as key-value pairs. Arrays use both the array and hash part of a Lua table while a dictionary only uses the hash part (no array-like functions work on it - ipairs and a majority, if not all, of the table library).

2 Likes

This won’t save the StringValue’s value though? How is this accepted as a solution?

And I actually did provide a valid answer to save both the Value object’s name and value here: How can I save everything in a folder? (In the datastores) - #2 by Avallachi

You can just save a table with the values too. + I thought of a way around it.

I believe the confusion here is between the meaning of a word and its connotation. In Lua, the connotation of the word array is a container (more formally known as a list) that has “indices” or “keys” starting at one and increasing in size relative to the size of the array. The technical definition of array, however, does not contain this meaning. It’s a more general concept that covers all kinds of key-value containers. However, even the PiL recognizes the more formal definition of the word array:
“We implement arrays in Lua simply by indexing tables with integers.” and “You can start an array at index 0, 1, or any other value”

I don’t see any reason to nitpick anyone for using the word array over the words dictionary or table. It is technically correct, and it is even a usage that extends across languages because it fits with the standard definition. The connotation, however, is not necessarily understood in other contexts. I understand that we’re in a specific context now, but, even within this context, it still isn’t inaccurate to use the more generalized meaning of the word.

I’m going based on the definition ArcRadians quoted.

3 Likes

I’m sorry for bumping this thread. But, here is the solution:

local Players = game:GetService("Players")

-- DataStores

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

local function PlayerJoined(player)
	local key = player.UserId
	
	local datastore = data:GetAsync(key)
	if datastore then
		-- add a system to load in data here
		print(datastore)
	else
		data:SetAsync(key, {}) -- new player, set data to nil
	end
end

local function PlayerRemoving(player)
	local key = player.UserId
	local datastore = data:GetAsync(key)
	
	pcall(function()
		local tab = {}
		
		for _, v in ipairs(player.Folder:GetDescendants()) do -- change this to your item
			table.insert(tab,{ v.Name, tostring(v.Value), v.ClassName })
		end
		
		if datastore:GetAsync(key) then
			datastore:UpdateAsync(key,function(oldVal)
				return tab
			end)
		else
			datastore:SetAsync(key, tab)
		end
	end)
end

game:BindToClose(function()
	if game.RunService:IsStudio() then
		return
	end
	
	for _, player in ipairs(Players:GetPlayers()) do
		coroutine.resume(coroutine.wrap(PlayerRemoving), player)
	end
end)

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

I do not use this solution anymore and I will not use it for future work. Instead, use profile service or datastore 2.

17 Likes

Thank you so much!! I was looking for this for days! I highly appreciate it! :grinning_face_with_smiling_eyes:

3 Likes