Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
3

I am having issue with datastore service. Ideas?

Asked by 6 years ago

I am having trouble saving data. When I run it states "Unable to cast value to function".

local DataStoreService = game:GetService("DataStoreService")
local PointsStore = DataStoreService:GetDataStore("PointsStore")

local SaveLoop =  coroutine.create(function(plr)
    while true do
        wait(120)
        PointsStore:UpdateAsync(plr.UserId,plr.leaderstats.Points.Value)
    end
end)

game.Players.PlayerAdded:Connect(function(player)

    local leaderstats = Instance.new("Folder",player)
    leaderstats.Name = "leaderstats"

    local Points = Instance.new("IntValue",leaderstats)
    Points.Name = "Points"

    Points.Value = PointsStore:GetAsync(player.UserId.."-Points") or 0

    coroutine.resume(SaveLoop,player)
end)

game.Players.PlayerRemoving:Connect(function(player)
    PointsStore:UpdateAsync(player.UserId.."-Points",player.leaderstats.Points.Value)
end)
0
Do you think you could use print statements to find where this error derives from? Also, you seem to be overusing UpdateAsync in my experience. SummerEquinox 643 — 6y

1 answer

Log in to vote
3
Answered by 6 years ago

:UpdateAsync() takes a function, not the value to update the data store with. Note that, if the passted function does not return or it returns nil, the update is cancelled. The function cannot yield either, so do not call wait() ,event:Wait(), etc

PointsStore:UpdateAsync(player.UserId .. "-Points", function(prev) -- prev is the previousvalue
    return player.leaderstats.Points.Value
end)

Also, why are you using coroutines like this? You should just move your while loop to the bottom of your script. Additionally, Instance.new's second argument is deprecated. Set all the properties of an object first, and then parent.

local Players = game:GetService("Players") -- Stay consistent! Why call :GetService() on DataStoreService and not Players? Why not have a variable for Players as well?
local DataStoreService = game:GetService("DataStoreService")
local PointsStore = DataStoreService:GetDataStore("PointsStore")

Players.PlayerAdded:Connect(function(player)
    local success, points = pcall(PointsStore.GetAsync, PointsStore, player.UserId .. "-Points") -- wrap web requests (data stores, http requests, etc) in pcalls
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local Points = Instance.new("IntValue")
    Points.Name = "Points"
    Points.Value = success and points or 0
    Points.Parent = leaderstats
end)

Players.PlayerRemoving:Connect(function(player)
    PointsStore:UpdateAsync(player.UserId .. "-Points", function(prev)
        return player.leaderstats.Points.Value
    end)
end)

game:BindToClose(function()
    --[[
        When a server is shutting down,
        it focuses only on shutting down,
        so your PlayerRemoving event listener will not be called. 
        You should save on BindToClose as well.
    --]]

    local playersInGame = Players:GetPlayers()

    for _, player in ipairs(playersInGame) do
        spawn(function()
            PointsStore:UpdateAsync(player.UserId .. "-Points", function(prev)
                return player.leaderstats.Points.Value
            end)
        end)
    end
end)
0
y u not using the prev parameter User#23365 30 — 6y
0
thanks incapaxian jakebball2014 84 — 6y
Ad

Answer this question