Dictionaries not saving in DataStores

Hello,
This is the same situation as my previous topic, but now a slightly different problem; dictionaries that I’ve made to save when the player leaves are nil when the player loads in. Do number arrays and dictionaries in the same datastore cause issues?

I didn’t think that the old number arrays had much of an impact so I didn’t include them last time, but now I will (It was a big mistake on my part for not including them).

local plrKey = "stat_"..p.UserId
local GetSaved
	
	local function GetData()
		local sucess, err = pcall(function()	
			GetSaved = DS:GetAsync(plrKey)
		end)
	
		if GetSaved then
			p.Class.Value = GetSaved[1]
			pts.Value = GetSaved[2]

			local num = 2
		
			for i, v in pairs (p.ClassStats:GetChildren()) do
				for i, e in pairs(v:GetChildren()) do
					if e.Name ~= "TickTime" then
							local t = {}
						t = GetSaved[v.Name] or {}
						if GetSaved[v.Name] ~= nil then
							e.Value = GetSaved[v.Name][e.Name]
						else
							GetSaved[v.Name] = {}
						end
						
							print(t, GetSaved[v.Name])
					end
				end
			end
			
			
			for i, v in pairs (p.leaderstats:GetChildren()) do
				if v.Name ~= "Points" then
					num = num + 1
					v.Value = GetSaved[num]
				end
			end
			
			
			num = num + 1
		
			local L = Instance.new("BoolValue")
			L.Name = "loaded"
			L.Parent = p
			warn("Data Loaded")
		end
	end
	
		GetData()
		wait(1)
		
		if GetSaved == nil then
			GetData()
			warn("Data Load failed, retrying")
			wait(1)
			if GetSaved == nil then
				warn("Data Load failed, retrying")
				GetData()
				wait(1)
				
				if GetSaved == nil then
					warn("Data load failed")
					
					local NumbersForSaving = {
						p.Class.Value,
						pts.Value,
					}

					for i, v in pairs (p.ClassStats:GetChildren()) do
						for i, e in pairs(v:GetChildren()) do
							if e.Name ~= "TickTime" then
								NumbersForSaving[v.Name] = {}
								NumbersForSaving[v.Name][e.Name] = e.Value
							end
						end
				end
				
				for i, v in pairs (p.leaderstats:GetChildren()) do
					if v.Name ~= "Points" then
						table.insert(NumbersForSaving, #NumbersForSaving + 1, v.Value)
					end
				end
					
					local L = Instance.new("BoolValue")
					L.Name = "loaded"
					L.Parent = p
					
					wait()
				DS:GetAsync(plrKey, NumbersForSaving)
				wait(1)
				p:LoadCharacter()
				end
			end
		end


game.Players.PlayerRemoving:Connect(function(p)
	local Table = {
		p.Class.Value,
		p.leaderstats.Points.Value,
}
	
	local f = p.ClassStats[p.Class.Value]
	f["Time Played"].Value = f["Time Played"].Value + tick() - f.TickTime.Value
	
	for i, v in pairs (p.ClassStats:GetChildren()) do
		for i, e in pairs(v:GetChildren()) do		
			if e.Name ~= "TickTime" then
				Table[v.Name] = {}
				Table[v.Name][e.Name] = e.Value
			end
		end
	end
	
	
	
	for i, v in pairs (p.leaderstats:GetChildren()) do
		if v.Name ~= "Points" then
			table.insert(Table, #Table + 1, v.Value)
		end
	end
	
	
	if p:FindFirstChild("loaded") then
		local success, err = pcall(function()
			DS:SetAsync("stat_"..p.UserId, Table)
		end)

		if success then
			warn("Saved Data")
		else
			warn(err)
		end
	end
end)
1 Like

I think you are using GetAsync instead of SetAsync. Did you mean:

DS:SetAsync(plrKey, NumbersForSaving)
1 Like

no, it’s not that. The problem is more here

if GetSaved then
			p.Class.Value = GetSaved[1]
			pts.Value = GetSaved[2]

			local num = 2
		
			for i, v in pairs (p.ClassStats:GetChildren()) do
				for i, e in pairs(v:GetChildren()) do
					if e.Name ~= "TickTime" then
							local t = {}
						t = GetSaved[v.Name] or {} --- for some reason, GetSaved[v.Name] is ALWAYS nil
						if GetSaved[v.Name] ~= nil then 
							e.Value = GetSaved[v.Name][e.Name]
						else
							GetSaved[v.Name] = {}
						end
						
							print(t, GetSaved[v.Name])
					end
				end
			end
			
			
			for i, v in pairs (p.leaderstats:GetChildren()) do
				if v.Name ~= "Points" then
					num = num + 1
					v.Value = GetSaved[num]
				end
			end
			
			
			num = num + 1
		
			local L = Instance.new("BoolValue")
			L.Name = "loaded"
			L.Parent = p
			warn("Data Loaded")
		end
1 Like

Well, maybe you could just try to encode it as JSON and store it as a string.

local HttpService = game:GetService("HttpService")

-- Use this when you need to store something
DS:SetAsync(key, HttpService:JSONEncode(value))

-- Use this when you need to get something
HttpService:JSONDecode(DS:GetAsync(key))

And, are you sure that the problem is occuring in the code block you showed me? Can you just print(GetSaved) and see if it says nil?

1 Like

yeah I’ve printed it and it was nil

1 Like

Ok, then try to JSON encode and decode your tables when you write/read to the datastore.

1 Like

would it screw up anything if “value” is a table?

1 Like

No, JSON is actually for encoding and decoding tables.

Have you tried this yet? Have you had any success?

1 Like

it didn’t work… When I added that line, another line in the script made an error

1 Like

Dictionaries can be saved just fine in datastores, so long as they aren’t mixed. Are you sure that your save function is working properly?

1 Like

What is the error that you are getting?

1 Like

hold on I’m retrying it since I think I accidentally added a line

1 Like

ok so there is an error caused by the JSON code: invalid argument #3 (string expected, got nil)

local GetSaved
	
	local function GetData()
		local sucess, err = pcall(function()	
			GetSaved = HttpService:JSONDecode(DS:GetAsync(plrKey))
		end)

if GetSaved then
			p.Class.Value = GetSaved[1] -- the error happens here
			pts.Value = GetSaved[2]

			local num = 2
		
			for i, v in pairs (p.ClassStats:GetChildren()) do
				for i, e in pairs(v:GetChildren()) do
					if e.Name ~= "TickTime" then
							local t = {}
						t = GetSaved[v.Name] 
						if GetSaved[v.Name] ~= nil then 
							e.Value = GetSaved[v.Name][e.Name]
						else
							GetSaved[v.Name] = {}
						end
						
							print(t, GetSaved[v.Name])
					end
				end
			end
			
			
			for i, v in pairs (p.leaderstats:GetChildren()) do
				if v.Name ~= "Points" then
					num = num + 1
					v.Value = GetSaved[num]
				end
			end
			
			
			num = num + 1
		
			local L = Instance.new("BoolValue")
			L.Name = "loaded"
			L.Parent = p
			warn("Data Loaded")
		end
1 Like

What line is it on? Can you also paste the code on that line please.

1 Like

I showed where it happens; it happens near the top where it says p.Class.Value = GetSaved[1]

1 Like

I just need to see the line.

See, at the end, where it says 2, please take a screenshot of line 2 in your code, like this:
image

1 Like

Please show me a picture of the error and a snippet of that line only.

I’m sending the line version I didn’t understand what you meant at first

image
image