Issue with saving tables

So, for the past few weeks, I’ve been working on a building system w/ saving, however, I’ve had issues with saving the furniture inventory from the beginning, alright. I’ve decided to try to fix it myself, a few weeks later, I unfortunately still wasn’t able to fix it, so here I am. Thank you everybody in advance.

Function to buy the furniture

	print("bought and added")
	local Furniture = {playerData:GetAsync(player.UserId.."-Furniture")}
	table.insert(Furniture, furnitureName)
	local FurJSON = game:GetService("HttpService"):JSONEncode(Furniture)
	local success, errormessage = pcall(function()
		playerData:SetAsync(player.UserId.."-Furniture", FurJSON)
	end)

	if success then
		print("Data successfully saved!")
	else
		print("There was an error while saving the data")
		warn(errormessage)
	end

Function to send the furniture

	print("sending")
	wait(4)
	game.ReplicatedStorage.Remotes.LoadFurniture:FireClient(player, playerData:GetAsync(player.UserId.."-Furniture"))
	return playerData:GetAsync(player.UserId.."-Furniture")

Placing function:

	local Furniture = playerData:GetAsync(player.UserId.."-Furniture")
	local FurJSON = game:GetService("HttpService"):JSONDecode(Furniture)
	for i, v in pairs(FurJSON) do
		if furnitureName == v then
			table.remove(FurJSON, i)
			break
		end
	end
	local New = game:GetService("HttpService"):JSONEncode(FurJSON)
	local success, errormessage = pcall(function()
		playerData:SetAsync(player.UserId.."-Furniture", New)
	end)

	if success then
		print("Data successfully saved!")
	else
		print("There was an error while saving the data")
		warn(errormessage)
	end
	game.ReplicatedStorage.Remotes.LoadFurniture:FireClient(player, playerData:GetAsync(player.UserId.."-Furniture"))

The function which is used to get the furniture, local:

	print("GotData")
	local ActualF = {Furniture}
	local t = {}
	for i, x in pairs(ActualF) do
		table.insert(t, x)
	end
	print(t)
	for i, x in pairs(script.Parent.Building.Furniture:GetChildren()) do
		if x.ClassName ~= "UIGridLayout" then
			x:Destroy()
		end
	end	
	for i, x in pairs(game.ReplicatedStorage.Furniture:GetChildren()) do
		for i, xx in ipairs(t) do
			--for index = 1, #Furniture do
			--local xx = Furniture[index]
			print("man")
			if x.Name == xx then
				print("Match found")
				local Frame = script.Parent.Building.FurniturePiece:Clone()
				Frame.Parent = script.Parent.Building.Furniture
				Frame.Visible = true
				x:Clone().Parent = Frame.ViewportFrame
				Frame.FurnitureName.Value = x.Name
			end
		end
	end;
3 Likes

Check out my tutorial I made!

1 Like

From reading the tutorial, and my understanding of it, I’m assuming I have to put the table values into a folder in the Player, getting it from there instead of getting the table to the client-side and then getting all the necessary UI stuff, am I correct?

1 Like

I tried to approach the script that way, and it ended with this
print.txt (778.0 KB)
Had to make it a .txt file because it didn’t let me upload the print itself because of how long it is.

IDK if this is the issue you are having, but I feel like the first line of this is creating a table within a table, and you may not be accessing the individual items in the table.

local Furniture = {playerData:GetAsync(player.UserId.."-Furniture")}
	table.insert(Furniture, furnitureName)
	local FurJSON = game:GetService("HttpService"):JSONEncode(Furniture)
	local success, errormessage = pcall(function()
		playerData:SetAsync(player.UserId.."-Furniture", FurJSON)
	end)

maybe replacing it with just local Furniture = playerData:GetAsync(player.UserId.."-Furniture") could help out any issues

2 Likes

Tried to do that, got this;
14:20:36.303 Unable to assign property Name. string expected, got string - Server - DataStore:166

And still prints out this

After doing something (Idek what), it now prints out:

  14:37:40.286  table: 0x00080ddf72450e5e  -  Server - DataStore:165

I usually use setasync and I access stuff from tables with carrot brackets.

Also, you can put a table inside of a table if you need to.

Forgot to post the script;
Now instead of being a function on itself, it gives the data to a folder in the player, instead of to the local script.

if Furniture ~= nil then
			print("aa")
			local Table = game:GetService("HttpService"):JSONDecode(Furniture)
			local Instances = {unpack(Table)}
			for i, x in pairs(Instances) do
				print("New")
				print(i)
				print(Instances)
				local Furniture = Instance.new("BoolValue")
				Furniture.Name = i
				Furniture.Parent = player.StatsIg.Furniture
			end
		end

Turns out, it still working as intended, I was meant to print(x) instead of print(i), and by printing x, I once again get this:

… I don’t even know what is going on in that output there…

Have you been clearing the datastores after each test? If not, I recommend you do so - it could be old data breaking it.

1 Like

I didn’t, and after doing so, it pretty much started working, it now prints genuine information, instead of nonsense! However, I’m not really sure how do I get that “Table” part out of the x.
[0,null,"Table"]

After trying multiple ways to get the “Table” out of it, such as:

print(xx[3])
for i, x in pairs(xx) do
if game.ReplicatedStorage:FindFirstChild(xx) do
print(x)
end
end

I am still unfortunately unable to resolve this issue.

I gotta say that you’ve updated the information in your comments way too many times and it’s too hard for me to process all of this. So pardon me if what I said was said / resolved.

My approach on saving player’s data is A) Adding a playerStats folder inside the player (like hunger or money)
B) Adding a folder in ServerStorage named “GLOBALPLAYERSTATS” and then once a player joins, add a folder with their UserId.

Then (using any approach you want.) I use this script to serialize a folder:

function cframeToTable(cf)
    return {cf:GetComponents()};
end
function tableToCframe(t)
    return CFrame.new(table.unpack(t));
end
function vectorToTable(vector)
    return {X = vector.X, Y = vector.Y, Z = vector.Z}
end
function tableToVector(t)
    return Vector3.new(t.X, t.Y, t.Z)
end

FolderData = {}
for i, v in ipairs(FOLDER:GetChildren()) do
    --[[ values ]]
    FolderData[v.Name] = v.Value -- THIS WOULD ONLY WORK FOR STRINGS/NUMBERVALUE/INTS. Use the encoders ive sent above for special dataTypes!
    -- You can use :IsA("VectorValue") to check what i've said on the line above
    -- Also you can change the key value to whatever you want, it was just an example
    
    --[[ instances ]]
    -- we also need to serialize data types as these are not supported for JSON encoding! (I've also given you some encoders/decores for that on top)
    local instanceInfo = {}
    instanceInfo.CFrame = cframeToTable(v.CFrame)-- this saves the cframe with the key CFrame <- i recommend you use cframe as it also saves the rotation 
    instanceInfo.Name =  v.Name                  -- this saves the name with the key Name 
    instanceInfo.Size = vectorToTable(v.Size)    -- this saves the size with the key Size 
    -- Btw: table.Key is equivalent to table["Key"]
    table.insert( FolderData, instanceInfo ) -- then we add the info
end

You can totally change the functions for serializing special datatype values
→ I haven’t added the un-serializing part because I believe it’s easy to do if you understand what I’ve sent :wink:

That said, good luck!

1 Like

I had the same issue a while back, someone solved it for me, k would recommend looking at this code Help with fixing data stores - #4 by maxxswrld

1 Like

Sorry for late response

Hello! From how I understand this, I am supposed to basically put the values into a Folder, and then I’ll get/save the data out of that folder, correct me if I’m wrong.

-After taking my take on it, it didn’t seem to work, I am not sure whether I am doing it incorrectly, or so.

Maybe you are doing something wrong. Could you send a screenshot of your current setup and the code you used?