Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

MetaTable to JSON?

Simply put I have a script similar to this-->

local maintable = {}
local addtable = {"Stuff","MoreStuff"}
local metatable = {"MoreMoreStuff","ExtraMoreStuff"} 
setmetatable(addtable,metatable)
table.insert(maintable,1,addtable)
 

local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore")
local http = game:GetService("HttpService")
local JSON = http:JSONEncode(maintable)
DataStore:SetAsync("JsonSave",JSON)

The whole thing works fine and when I load the JSON again I have everything... except the meta table. I try-->

--Of course not in the same script
local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore")
local LoadedMainTable = DataStore:GetAsync("JsonSave")
local Decodedtable = http:JSONDecode(LoadedMainTable)
local addtable = Decodedtable[1] 
 if addtable then
	local metatable = getmetatable(addtable)
	if metatable then
		print("GotMetaTable")
	else
		print("--MetaTable = nil")
	end
end

This script results in this in the output-->

--MetaTable = nil

So my question is: Does JSONEncode/Decode get ride of all meta tables? If not then how would you successfully get a meta table from a decoded JSON format?

2 comments

0

This looks like a job for, BlueTaslem!

0

Updated with code -- apologies, I've been without internet

1 answer

✓ Accepted answer

Metatables can't be meaningfully serialized (turned into text) because they have functions attached to them. (This is documented)

This is impossible because functions can be closures--they can refer to particular variables ruining in the program, which doesn't make sense to give to someone on another computer.

I would suggest making an extra property recording the "type" of the thing, and looking up the appropriate metatable and then applying it.


Here is an example of the kind of thing I am suggesting:

function setupHouse(data)
	setmetatable(data, houseMeta)
end

function setupLine(data)
	setmetatable(data, lineMeta)
end

-- `data` is the result of DecodeJSON.
-- It attaches the appropriate metatable
function receiveData(data)
	if data.type == "house" then
		setupHouse(data)
	elseif data.type == "line" then
		setupLine(data)
	elseif ... etc then

	end
end

Then you have to remember that when you serialize to JSON, you have to include the proper .type property.

You can shorten all of the elseifs using a dictionary:

local metas = {
	house = houseMeta,
	line = lineMeta,
	dog = dogMeta,
	-- etc
}

function receiveData(data)
	local meta = metas[data.type]
	if meta then
		setmetatable(data, meta)
	end
end

-- adds the `.type` property to `.data`, which is an object with (maybe) a metatable
-- (use :EncodeJSON on the `data` after this)
function sendData(data)
	local meta = getmetatable(data)
	for kind, m in pairs(metas) do
		if m == meta then
			data.type = kind
		end
	end
end

1 comment

0

Could you please give me some example code to go off of.

This discussion is preserved as it was. New answers, comments, and votes are closed.