I keep on receiving this error: Unable to cast value to function
I have made sure that the data store key is the same, and that the table does get successfully sent to the server.
Here is my function that contains the error (Note, it’s on a server script): The error is on expDataStore:UpdateAsync(plrId,newData
game.Players.PlayerRemoving:Connect(function()
dataEvent.OnServerEvent:Connect(function(plr,newData)
for i,v in pairs(game.Players:GetPlayers()) do
if v == plr then
local plrId = "Player_"..plr.UserId
local success, err = pcall(function()
expDataStore:SetAsync(plrId,newData)
end)
if err then
warn(err)
end
end
end
end)
end)
i believe that the PlayerRemoving event has some time before the player actually leaves that game but why not just save the data when it changes? plus, you already have the player parameter, why use a for i, v loop to look for it? you put it in a PlayerRemoving event
I’m using the for i,v loop to make sure I’m saving the data on the correct player, since It’s a server script, not looking for the player. (I’m pretty sure there’s an easier way to do this, but this is the way I figured out how to do it.)
Two things I had noticed. For starters, you nested an event, which should be avoided unless the second event is a dependent of the first. The second one was that if you test in Studio, it might not save anyways because the game closes before the data can save. You can fix this by testing in Team Test and using the following code:
local plrs = game:GetService("Players")
function saveData(plr, newData)
local plrId = "Player_"..plr.UserId
local success, err = pcall(function()
expDataStore:SetAsync(plrId, newData)
end)
if err then
warn(err)
end
end
plrs.PlayerRemoving:Connect(function(plr)
saveData(plr, Define.Whatever.You.Want.To.Save)
end)
game:BindToClose(function()
if game:GetService("RunService"):IsStudio() then return end
for index, plr in pairs(plrs:GetPlayers()) do
saveData(plr, Define.Whatever.You.Want.To.Save)
end
end)
:BindToClose() is an event that will keep the server open until the handler has finished executing.
Thanks for the help, at the moment I am unable to open Studio and test the code, but if it’s not a problem, would you mind giving me an example of when you would combine two events?
The variable newData is not a function, therefor Roblox cannot call that “function”. Try using SetAsync() instead of UpdateAsync(), as it doesn’t need a function as the second parameter. UpdateAsync() calls the second parameter (which is meant to be a function) and sets the value of the store to what the function returns.
Of course! You should only use nested events when the second event comes from a parameter in the first event. For example:
game.Players.PlayerAdded:Connect(function(plr) --Plr is the variable we will use for the second event
plr.CharacterAdded:Connect(function(char) --This events uses the first param of "plr" as its base
--Char here represents the character of the player
end)
end)
If the variables are needed in the global scope, then you can create separate event handlers. An example of that would be:
local data --I left it undefined so we can give it a value later
game.ReplicatedStorage.SomeRemoteEvent.OnClientEvent:Connect(function(text)
data = text --Change the value of "data" to what was recieved from the server
end)
game.Players.PlayerRemoving:Connect(function(plr)
if plr == game.Players.LocalPlayer then
print(plr.Name.. "'s text was: ".. tostring(data))
end
end)
So there still an issue with the code. So I have to store a table, and I tried to do the thing you explained with using the remote event to define an undefined variable then using that variable, but it didn’t work. I have already made sure that the table is being sent to the server.
local data
dataEvent.OnServerEvent:Connect(function(plr,newData)
data = newData
end)
local plrs = game:GetService("Players")
function saveData(plr, newData)
local plrId = "Player_"..plr.UserId
local success, err = pcall(function()
expDataStore:SetAsync(plrId, newData)
end)
if err then
warn(err)
end
end
plrs.PlayerRemoving:Connect(function(plr)
saveData(plr, data)
end)
game:BindToClose(function()
if game:GetService("RunService"):IsStudio() then return end
for index, plr in pairs(plrs:GetPlayers()) do
saveData(plr, data)
end
end)
Mkay, and here’s the local script that sends the data if you need it for testing. It’s inside of StarterPlayerScripts.
local data = {
newlvl = lvl,
newexp = exp,
newexpToNextLvl = expToNextLvl,
newlvlMult = lvlMult
}
coroutine.resume(coroutine.create(function()
while wait(.1) do
dataEvent:FireServer(data)
end
end))