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

Table expected, got nil & Attempt to index upvalue (a nil value)?

Asked by 4 years ago

So, I'm trying to save a Table using DataStore. It's coming up with 2 errors. I'm trying to print every value inside of the table and it's giving me this error

16:26:55.044 - ServerScriptService.Script:16: bad argument #1 to 'pairs' (table expected, got nil)

16:26:55.044 - Stack Begin

16:26:55.044 - Script 'ServerScriptService.Script', Line 16

16:26:55.045 - Stack End

And everytime I exit my test in studio, or in a live server, it gives me this error when I'm trying to save my table.

16:26:56.480 - ServerScriptService.Script:25: attempt to index upvalue 'testList' (a nil value)

This is the ServerScript inside of ServerScriptService

local testList = {33788911}
local testStore = game:GetService("DataStoreService"):GetDataStore("TestStore")

game.Players.PlayerAdded:Connect(function(player)
    local success,errorMessage = pcall(function()
        newList = testStore:GetAsync("testData-KB")
    end)

    if success then
        testList = newList
        print("Test Data Was Loaded!")
    else
        warn(errorMessage.." | There Was An Error Loading Test Data!")
    end

    for _,p_ID in pairs(testList) do
        if player.UserId == p_ID then
            print("Special Player "..player.Name.." Has Arrived!")
        end
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local success, errorMessage = pcall(function()
        testList:SetAsync("testData-KB",testList)
    end)

    if success then
        print("Test Data Was Saved!")
    else
        warn(errorMessage.." | There Was An Error In Saving The Test Data!")
    end
end)

I'm not sure if I've formatted something wrong or if I just did this wrong in general.

2 answers

Log in to vote
1
Answered by 4 years ago

There are quite a lot of errors here. I'll give you a list of each and how to fix them.

  1. You have to remember to make an actual variable for variables you're giving values too. In this case, you didn't set the value for 'newList' when you were giving it a value (if data was found). The reason you weren't getting an error for that is because the data was returning nil because nothing was being saved in the first place. I'll get into that part later though.

To fix this, you simply need to make the variable first.

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

    local NewList --New Variable

    local success, err = pcall(function()
        NewList = testStore:GetAsync('testData-KB')
    end)


    if NewList and type(NewList) == 'table' then else return end --ends the function if data was not found or the data was not a table
end

Also, I would recommend using function based variables for datastores. In yours you used a script wide variable 'TestList' accessible by all the functions. Which can easily cause data errors. So instead, put that variable inside the PlayerAdded function.

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

    local NewList

    local TestList  = {} --Inside the function

    local success, err = pcall(function()
        NewList = testStore:GetAsync('testData-KB')
    end)


    if NewList then else return end

    if success then
        TestList = NewList
        print('Test Data Found')
    else
        warn('There was an error finding Test Data for '..plr.Name)
    end

end

However after looking at the rest of your script, you clearly want it to say that a player has entered the game if their user ID is found. So just include a separate table with the UserID's you want, then go through that with a for loop. Like this

local IDs = {1111} -- (player id you want to check)

for i, v in pairs(IDs) do
    if plr.UserId == v then
        print(plr.Name..' has joined the game!')
    end
end
  1. When the player leaves the game, you aren't actually saving any data.

You did 'testList:SetAsync' which wouldn't do anything, since testList is a table and not a DataStore. I think what you meant to do is something like this...

game.Players.PlayerRemoving:Connect(function(plr)
    local PlayerData = testData:GetAsync('testData-KB')

    if PlayerData and type(PlayerData) == 'table' then
        testData:SetAsync('testData-KB', PlayerData)
    else
        warn('Failed to save data for '..plr.Name)
    end
end

What it looks like you're trying to do here is just print something when a certain player joins the game. You don't need datastores to do this. All you need to do is something like this

local SpecialList = {19034023, 23049023, 32949205} --random ID's of the players you want announced when they join

game.Players.PlayerAdded:Connect(function(plr)
    for i, v in pairs(SpecialList) do
        if v == plr.UserId then
            print('The special '..plr.Name..' has joined the server!')
        end
    end
end

If this doesn't make sense to you, try looking more at DataStores here

0
Thanks too! Your's was just a bit more detailed killerbrenden 1537 — 4y
Ad
Log in to vote
1
Answered by 4 years ago

First error: Global variable testlist got changed to nil on line 10 because new data defaults to nil.

Second error: as mentioned in the first error, since you changed a global testlist to nil. So that error occurred as well.

I'd recommend to check if the value is nil or not.

if not testlist then
    testlist={}; -- this is a replacement value.
end;
0
Thanks! killerbrenden 1537 — 4y

Answer this question