Saving DataStore Not Working

game.Players.PlayerAdded:Connect(function(player)
	local key = player.UserId
	
	local data = myDataStore:GetAsync(key)
	
	for _, folder in pairs(script:GetChildren()) do

		if folder:IsA("Folder") then

			local fc = folder:Clone()
			fc.Parent = player


			for _, item in pairs(fc:GetChildren()) do
				if data and item:IsA("StringValue") and item:IsA("BoolValue") and item:IsA("NumberValue") then
					print(data)
					task.wait()
					item.Value = data[item.Name]
				else
					warn("There is no data")
				end
			end
		end
	end
end)

This is under game.players.playeradded it print there no data everytime a player joins the game.

local function create_table(plr)
	local player_stats = {}
	
	for _, folder in pairs(script:GetChildren()) do
		if folder:IsA("Folder") then
			for _, stat in pairs(plr:FindFirstChild(folder.Name):GetChildren()) do
				--if stat:IsA("StringValue") and stat:IsA("BoolValue") and stat:IsA("NumberValue") then
					player_stats[stat.Name] = stat.Value
				--end
			end
		end
	end
	
	return player_stats
end

game.Players.PlayerRemoving:Connect(function(plr)
	local player_stats = create_table(plr)
	
	local success, err = pcall(function()
		local key = plr.UserId
		myDataStore:SetAsync(key, player_stats)
	end)
	
	if success then
		print("Saved data correctly")
	else
		warn(err)
	end
end)

This is my attempt of saving data.

When the player teleports this is how I send the data there under the same place.

local function create_table(plr)
	local player_stats = {}

	for _, folder in pairs(script:GetChildren()) do
		if folder:IsA("Folder") then
			for _, stat in pairs(plr:FindFirstChild(folder.Name):GetChildren()) do
				if stat:IsA("StringValue") and stat:IsA("BoolValue") and stat:IsA("NumberValue") then
					player_stats[stat.Name] = stat.Value
				end
			end
		end
	end

	return player_stats
end

Basically there is folders under datastore this script supposed to loop through all the folders get the string number or bool values inside the folder and save the data. Everytime a player joins it prints there no data multiple times. Any solutions?

As far as I know, You can’t save tables in datastore BUT there’s an alternative way to do it.

Check my reply to this post:
https://devforum.roblox.com/t/how-to-load-a-table-saved-in-a-datastore/1912879/2

Can you show me an example with my case. In my script Im not saving one folder Im saving multiple.

Eventually, use profile service. This data saving method breaks after a certain amount of traffic on your game.

1 Like

I don’t think item can all be StringValue, BoolValue, AND NumberValue all at the same time

2 Likes

I’ve tried this but I haven’t tested it in studio or in-game. let me know if something happens.

local Players = game:GetService("Players")
local DS = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")

local DS_DATA = DS:GetDataStore("DS_DATA_0001") -- sample name of datastore

Players.PlayerAdded:Connect(function(thisPlayer)
	local Key = thisPlayer.UserId
	
	-- Load
	local PLAYER_DATA = nil
	repeat
		local success, message = pcall(function()
			DS_DATA:GetAsync(Key)
		end)
		
		if not success then
			warn(message) -- if something went wrong, then reload the loading of data.
		end
		task.wait(1)
	until success == true
	
	-- Check if the data is not nil, then convert it to table
	if PLAYER_DATA ~= nil then
		repeat
			local Decode = nil
			local success, message = pcall(function()
				Decode = HttpService:JSONDecode(PLAYER_DATA) -- the thing.
			end)
			
			if Decode ~= nil then
				PLAYER_DATA = Decode
			end
			
			if not success then
				warn(message)
			end
		until success == true
	end
	
	-- Clone stuffs
	for index1, Folder in pairs(script:GetChildren()) do
		if Folder:IsA("Folder") then
			
			-- Clone
			local newFolder = Folder:Clone()
			newFolder.Parent = thisPlayer
			
			-- Set Values
			-- check your variables (Ex. index1, index2)
			for index2, item in pairs(newFolder:GetChildren()) do
				if item:IsA("StringValue") or item:IsA("NumberValue") or item:IsA("BoolValue") then
					-- Since the PLAYER_DATA is now a table.
					local FIND_DATA = table.find(PLAYER_DATA, item.Name) -- returns the index or the position of the data we're looking for. (If there is)
					if FIND_DATA then
						item.Value = PLAYER_DATA[FIND_DATA]
					else
						warn(item.Name, "not found in the saved data.")
					end
					task.wait(0.01)
				end
			end
		end
	end
end)

local function CREATE_TABLE(Player)
	local player_stats = {}

	for _, folder in pairs(script:GetChildren()) do
		if folder:IsA("Folder") then
			for _, stat in pairs(Player:FindFirstChild(folder.Name):GetChildren()) do
				if stat:IsA("StringValue") or stat:IsA("BoolValue") or stat:IsA("NumberValue") then
					player_stats[stat.Name] = stat.Value
				end
			end
		end
	end

	return player_stats
end


Players.PlayerRemoving:Connect(function(thisPlayer)
	local toTable = CREATE_TABLE(thisPlayer)
	
	if not toTable then
		warn("Error while converting values into table.")
		return -- exit
	end
	
	-- Saving
	-- Convert to JSON String.
	local CONVERT_DATA = nil
	repeat
		local Encode = nil
		local success, message = pcall(function()
			Encode = HttpService:JSONEncode(toTable)
		end)
		if Encode ~= nil then
			CONVERT_DATA = Encode
		end
		if not success then
			warn(message)
		end
		task.wait(0.01)
	until success == true
	
	if CONVERT_DATA ~= nil then
		repeat
			local succ, message = pcall(function()
				DS_DATA:SetAsync(thisPlayer.UserId, CONVERT_DATA) -- save
			end)
			task.wait(0.01)
			if not succ	then
				warn(message)
			end
		until succ == true
	else
		warn("Invalid data while saving. Contains nil value.")
	end
end)
1 Like

Thanks both of your methods work.

Yeah that why it wasnt working good looks.