As the title of the post says I am attempting to use a dataTemplate with nested tables inside of it for ProfileService. I’ve done some research on how I could do this without having trouble, editing keys, setting values, or removing key, value pairs.
I’ve tried actually using them for a while but they haven’t been working. I’ve done deepCopy(dataTemplate), but it hasn’t worked.
In the Devforum Post, someone mentions a deep copy and uses it to set the Data, should I change my methods to use deep copies when I’m changing the values of tables?
Not 100% sure what the issue is? If you wanna edit nested tables, just access them traditionally.
local profile = ...
profile.Data.Table.TableA.Inventory.Amount = 1 -- very long way!
-- not very long way, aka just using variables
local tableA = profile.Data.Table.TableA
local inventory = tableA.Inventory
inventory.Amount = 1
If you are using ReplicaService:
local replica = ...
replica:SetValue({"Table", "TableA", "Inventory", "Amount"}, 1)
Also deep cloning/copies is just the equivalent of copying a table with more complex things like keys. This way you won’t interfere with the original table!
If I remove a key, value pair, it continues to stay in the nested table forever, if I change a key, the key still stays in the table forever, and if I update a value inside an array with old keys, nothing will change once the data is loaded and the player joins. (Not using ReplicaService)
Specifically for tables I always use this Update helper function:
function PlayerDataHandler:Set(player,key,value)
local profile = getProfile(player)
assert(profile.Data[key],string.format("Data does not exist for key: %s",key))
assert(type(profile.Data[key]) == type(value))
profile.Data[key] = value
if key == "Money" or key == "Level" or key == "Experience" then
Remotes.ToClient:FireClient(player,"UpdateCounters",PlayerDataHandler:Get(player,"Experience"),PlayerDataHandler:Get(player,"Level"),PlayerDataHandler:Get(player,"Money"))
end
end
function PlayerDataHandler:Update(player,key,callback)
local profile = getProfile(player)
local oldData = self:Get(player,key)
local newData = callback(oldData)
self:Set(player,key,newData)
end
Data:Update(player,"Abilities",function(current)
current[abilityName][2] += 1
return current
end)
Not sure if I’m right but I’m assuming the script actually just updates a copy of the Data you are trying to update (tables suck sometimes).
If you are using classes, you could also just set for example self.Profile to the profile you created in the constructor, then you can directly reference the profile without any issues.
-- example usage, do not actually use this lol
local Module = {}
local PlayerDataHandler = nil
-- Constructor
function Module.new(player)
local profile = ... make profile here and stuff
local this = { Player = player, Profile = profile }
setmetatable(this, PlayerDataHandler)
return this
end
PlayerDataHandler = {}
PlayerDataHandler.__index = PlayerDataHandler
function PlayerDataHandler:Set(key, value)
self.Profile.Data[key] = value
end