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

How do I fix this Issue with a datastore (invalid argument #3 (string expected, got nil)?

Asked by 3 years ago

When I Join the game it keeps say this error
ServerScriptService.DataStorage.RankCreator:36: invalid argument #3 (string expected, got nil):

The error is occuring at line 36

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("DataStore")

local function saveData(plr)

    local dataTable = plr.leaderstats("Rank").Value

    local success, err = pcall(function()
        dataStore:SetAsync(plr.UserId, dataTable) -- Save the data with the player UserId, and the table we wanna save
    end)

    if success then -- If the data has been saved
        print("Data has been saved!")
    else -- Else if the save failed
        print("Data hasn't been saved!")
        warn(err)       
    end
end

game.Players.PlayerAdded:Connect(function(plr)
    local leaderstats = Instance.new("Folder")
    leaderstats.Parent = plr
    leaderstats.Name = "leaderstats"

    local rank = Instance.new("StringValue")
    rank.Parent = leaderstats
    rank.Name = "Rank"

    local data -- We will define the data here so we can use it later, this data is the table we saved
    local success, err = pcall(function()
        data = dataStore:GetAsync(plr.UserId) -- Get the data from the datastore
        print("getting data...")
    end)

    if success then
        rank.Value = data
    else 
        print("The player has no data!")
    end

    rank.Changed:Connect(function()
        print("rank changed")
    end)

end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
    local success, err  = pcall(function()
        saveData(player) -- Save the data
    end)

    if success then
        print("Data has been saved")
    else
        print("Data has not been saved!")
    end
end)

3 answers

Log in to vote
0
Answered by 3 years ago

You didn't assign any value to data when you define it at Line 29 that's why it returned nil. rank.Value at Line 36 has to be string. Hope this helps!

0
Im pretty sure it defines data at line 31 EhEhEhEhLPKJ 9 — 3y
0
But it's not a string, is it? Dehydrocapsaicin 483 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

Success will be true even if there is no data. You will have to check if data exists as well before setting rank.Value.

Log in to vote
0
Answered by
sifn 70
3 years ago

The other answers to this question are indeed telling you the mistake you made, but it does not look like they are being quite clear enough on how exactly to apply the fix. In short, all you need at the very least is an and operator. However, I am going to go a little more in depth than that because I feel that this question stems from a lack of understanding of datastores. Let's go over this.

local data
local success, err = pcall(function()
    data = dataStore:GetAsync(plr.UserId)
    print("getting data...")
end)

if success then
    rank.Value = data
else 
    print("The player has no data!")
end

When making a datastore call like the above, the 'success' variable just indicates if the call made it over the network. So, you could ask for information from a datastore and you may find that the call is successful, but it doesn't mean that there is actually any data saved.

To elaborate on the why a datastore request might fail sometimes (and you might already know this!), when you ask for something over the network such as datastore information, that request has to make it over to Roblox's servers and hence could fail at times, usually because of a bad connection. The success variable tells you if it failed or not and that's its job. Again, it doesn't actually indicate that there is any saved data.

What you want to do is check if the call was successful AND if data was returned, and only then update your value object with the returned data.

if success and data then
    rank.Value = data
else
    print("The player has no data OR the datastore request failed!")
end

That's the fix. Very simple. Now, if you wish to handle datastore call failure in some way (retrying the request some number of times, etc.) you could take this a step further by firstly checking if the call was successful, then checking for the existence of saved data, like so:

if success then
    print("The datastore request was successful.")

    if data then
        print("Saved data found")
    else
        print("No saved data found")
    end
else
    print("The datastore request failed: "..err") -- Print the error message to see why the call failed if you're curious!
end

Answer this question