Data Saving - Table expected got nil

Trying to make a data-saving system where it reads the children in a folder in the player then translates it into a dictionary and saves said dictionary. However, when I try to load it in it errors and says that the dictionary doesn’t exist.

Data loading:

    local dataTableLoad = {}
    local playerKey = "Player_"..ourPlayer.UserId
	local success, errorMessage = pcall(function()
		dataTableLoad = leaderStatStore:GetAsync(playerKey)
	end)
	if success then
		for i, v in next, dataTableLoad do -- Errors here, Right now I just want it to print the variable name and the value	
			print(i)
			print(v)
		end
	else
		print(errorMessage)
	end

Data saving:

    local playerKey = "Player_"..ourPlayer.UserId
	if ourPlayer:FindFirstChild("PetInventory") then
		for i, v in pairs (ourPlayer.PetInventory:GetChildren())do
			dataTableSave[v.Name] = v.Value
		end
	end

    local success, errorMessage = pcall(function()
		leaderStatStore:SetAsync(playerKey, dataTableSave)
	end)
	if success then
		print("Data saving successful")
	else
		print("Not successful")
		warn(errorMessage)
	end
1 Like

Change
for i, v in next, dataTableLoad do
to
for i, v in pairs(dataTableLoad) do

1 Like

Still retrieves nil :frowning:

Change this to

dataTableLoad = leaderStatStore:GetAsync(playerKey) or {} as there is no data if they are a new player.

On another note, encode your tables using JSON

Encode table
Decode table

2 Likes

Doesn’t error but now it always loads in nothing.

1 Like

This is probably because no data is saved. You’ll need to make your code handle that. Did you encode, and decode the tables too?

1 Like

I haven’t encoded nor decoded.

1 Like

Try that, please. Also, ensure you are actually saving more than just a blank array.

1 Like

do not attempt to do that, anything that needs to be sent to a DataStore is internally turned into a string format, tables are JSONEncoded because Roblox’s DataStoreService interfaces with Dynamo DB, non-string formats are not acceptable for being stored.

JSONEncoding a table will essentially JSONEncode it twice, almost doubling the size.

@Carnibula you can’t load in data if it was never saved,
maybe try retrying if it didn’t save properly?

Try viewing retrieved data like this :

  for k, v in pairs (dataTableLoad) do
           print(k .." = "..v)
  end
2 Likes

Okay then, wasn’t aware of that. Well, as I said make sure your data is not blank that you’re saving.

2 Likes

I’ve tested the table when saving with this loop

for i, v in pairs (ourPlayer.PetInventory:GetChildren()) do
	print(dataTableSave[v.Name])
end

The results are fine?

1 Like

Then, forloop through dataTableSave and print the result, you should see the names. Do you?

1 Like

This isn’t necessary here, as we’re trying to find out why the data is not saving the tools names.

1 Like

Tested with this

for i, v in next, dataTableSave do		
	print(i)
	print(v)
end

It doesn’t print anything?

1 Like

please use for i,v in pairs(array) do, and if it isn’t that means that the table is blank, which explains why you are loading nothing.

try looking at this, also is PetInventory just a thing full of things like StringValues?

if ourPlayer:FindFirstChild("PetInventory") then
		for i, v in pairs (ourPlayer.PetInventory:GetChildren())do
                    print(I,v)
			dataTableSave[v.Name] = v.Value
		end
	end
1 Like
if ourPlayer:FindFirstChild("PetInventory") then
		for i, v in pairs (ourPlayer.PetInventory:GetChildren())do
                    print(I,v)
			dataTableSave[v.Name] = v.Value
		end
	end

So the code above does print back the strings inside PetInventory. (Yes pet inventory is full of string values).

1 Like

Cool, so to make sure we’re on the same page before I bring this into studio, can you send the two functions here again? I’m going to try to figure this out real quick.

1 Like
local dataStoreService = game:GetService("DataStoreService")
local leaderStatStore = dataStoreService:GetDataStore("test7")
local playerInGame = game.Players

local dataTableLoad
local dataTableSave = {}

playerInGame.PlayerAdded:Connect(function(ourPlayer)
	--// L O A D I N G \\--
	
	local playerKey = "Player_"..ourPlayer.UserId
	local success, errorMessage = pcall(function()
		dataTableLoad = leaderStatStore:GetAsync(playerKey) or {}
	end)
	
	
	if success then
		print("Retrieving successful")
		for i, v in pairs(dataTableLoad) do	
			print(i)
			print(v)
		end
	else
		print(errorMessage)
	end
	--[[
	if success then
		print("successful retrieving data")
		local s, e = pcall(function()
			for i, v in pairs(dataTableLoad) do
				
				local newPet = Instance.new("StringValue")
				newPet.Parent = ourPlayer:WaitForChild("PetInventory")
				newPet.Value = v
				newPet.Name = i
				
				--v.Value = dataTableLoad[v.Name]
			end

		end)
	else
		print("No data, generating new data.")
		warn(errorMessage)
	end
	--]]
	

	
end)

playerInGame.PlayerRemoving:Connect(function(ourPlayer)
	
	--// S A V I N G \\--
	
	local playerKey = "Player_"..ourPlayer.UserId
	
	if ourPlayer:FindFirstChild("PetInventory") then
		for i, v in pairs (ourPlayer.PetInventory:GetChildren())do
            print(i,v)
			dataTableSave[v.Name] = v.Value
		end
	end
	
	local success, errorMessage = pcall(function()
		leaderStatStore:SetAsync(playerKey, dataTableSave)
	end)
	
	if success then
		print("Data saving successful")
	else
		print("Not successful")
		warn(errorMessage)
	end
	
end)

entire script :confused:

1 Like

Try this, going to update this message with code changes.

local dataStoreService = game:GetService("DataStoreService")
local leaderStatStore = dataStoreService:GetDataStore("test7")
local playerInGame = game.Players

playerInGame.PlayerAdded:Connect(function(ourPlayer)
	--// L O A D I N G \\--
	local dataTableLoad = {};
	
	local playerKey = "Player_"..ourPlayer.UserId
	local success, errorMessage = pcall(function()
		dataTableLoad = leaderStatStore:GetAsync(playerKey) or {}
	end)
	
	
	if success then
		print("Retrieving successful")
		for i, v in pairs(dataTableLoad) do	
			print(i)
			print(v.name, v.value)
		end
	else
		print(errorMessage)
	end
	--[[
	if success then
		print("successful retrieving data")
		local s, e = pcall(function()
			for i, v in pairs(dataTableLoad) do
				
				local newPet = Instance.new("StringValue")
				newPet.Parent = ourPlayer:WaitForChild("PetInventory")
				newPet.Value = v
				newPet.Name = i
				
				--v.Value = dataTableLoad[v.Name]
			end

		end)
	else
		print("No data, generating new data.")
		warn(errorMessage)
	end
	--]]
	

	
end)

playerInGame.PlayerRemoving:Connect(function(ourPlayer)
	local dataTableSave = {}
	
	--// S A V I N G \\--
	
	local playerKey = "Player_"..ourPlayer.UserId
	
	local toSave = {};
	
	if ourPlayer:FindFirstChild("PetInventory") then
		for i, v in pairs (ourPlayer.PetInventory:GetChildren())do
			table.insert(toSave, {
				name = v.Name,
				value = v.Value
			})
		end
	end
	
	local success, errorMessage = pcall(function()
		leaderStatStore:SetAsync(playerKey, dataTableSave)
	end)
	
	if success then
		print("Data saving successful")
	else
		print("Not successful")
		warn(errorMessage)
	end
	
end)

I noticed an issue where you had your saving/loading varibles as global varibles, this means all players would get the previous players who left/joined items. You want them inside their respective functions.

1 Like

Didn’t notice the global variables, thanks for making me aware. Any luck on the loading?