Help with saving tables to datastore

I would like to make a table that saves each Item amount, and species
(eg: amount: 5, species: wood)

I save the tables like this table arg 1 is species table arg 2 is amount but the studio keeps returning the data nil when try to get the data

I have searched on the forum but I dont think I saw anything

Here is my Code

local DataStoreService = game:GetService("DataStoreService")
local DS = DataStoreService:GetDataStore("NewItemsData")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local function ConpactDatatoTable(dataname, datavalue)
	return {
		dataname,
		datavalue
	}
end
	

game.Players.PlayerAdded:Connect(function(plr) 
	local itemsfolder = Instance.new("Folder", plr)
	itemsfolder.Name = "Items" 

	wait()
	local plrkey = "id_"..plr.userId
	local GetSaved = DS:GetAsync(plrkey)
	if GetSaved then 
		for _, itemtable in next, GetSaved do
			local newitemfold = Instance.new("Folder", itemsfolder)
			newitemfold.Name = itemtable[1]
			
			local Data1 = Instance.new("StringValue", newitemfold)
			Data1.Value = itemtable[1]
			Data1.Name = "Species"
			
			local Data2 = Instance.new("IntValue", newitemfold)
			Data2.Value = itemtable[2]
			Data2.Name = "Amount"
		end
	else
		local NumbersForSaving = {}
		DS:GetAsync(plrkey, NumbersForSaving)
	end
end)
game:BindToClose(function()
	if not RS:IsStudio() then
		local players = Players:GetPlayers()
		for _, player in pairs(players) do
			player:Kick("This server is shutting down")	
		end
		while true do
			wait()
		end
	else
		wait(5)
	end
end)
game.Players.PlayerRemoving:Connect(function(plr) 
	print("leaving") 
	for _, itemfolder in next, plr.Items:GetChildren() do
		local itemname = itemfolder.Species.Value
		local itemamount = itemfolder.Amount.Value
		DS:SetAsync("id_"..plr.userId, ConpactDatatoTable(itemname, itemamount))
	end	
end)
	 
	
	 
	

Any help would be appreciated thanks

1 Like

wait() isn’t needed here, also I recommend setting the parent for Instances last, because of performance issues.

You should wrap this in a pcall because it can fail to load and throw an error

to get the index and value, you should use for index, value in pairs(table) do

I recommend using UpdateAsync instead of SetAsync because it has a higher chance of causing data loss. Also, this loop resets the player’s data everytime it finishes.

Wouldn’t it be easier to do (depending on the context)

local function ConpactDatatoTable(dataname, datavalue)
	return {
		dataname = datavalue
	}
end

it seems to be trying to load data? I think? GetAsync only has one parameter

But if I’m trying to save the name, and the amount separately that wouldn’t work right?

in that context, it would work. the parameter names just suggested otherwise

So for the pcall I should try something like this?

	local Success, Error = pcall(function()
		local GetSaved = DS:GetAsync(plrkey)
	end)
	if Success == true then
1 Like
local Success, Error = pcall(function()
	return DS:GetAsync(plrkey)
end)

if Success == true then
   -- code
else
   warn ("error loading data: " .. Error)
end

so essentially, yes

if there’s no data to load then it will return nil, to combat this, just simply do

if Error then
  -- code
end

after the if Success == true then statement

Found problem, I forgot to put [1], and [2] in the table my bad

The second variable of the pcall can be used to return the data if success is true.

local Success, Data = pcall(function()
	return DS:GetAsync(plrkey)
end)

if Success and Data then --check if there is data as well

end

This essentially allows you to use the Error as the data. Data will be nil if success is false.

1 Like