"attempt to call method 'SetAsync' (a nil value )"

Hey, I’m trying to learn Lua, so I figured I’d go watch an AlvinBlox video. I have an error coming from a section of my leaderstats script (I put it in the title), and here’s the code it’s coming from:

game.Players.PlayerRemoving:Connect(function(plr)
	local tools = {}
	
	for i, tool in pairs(game.ServerStorage.PlayerTools[plr.Name]:GetChildren()) do
		table.insert(tools,tool.Name)
	end
	
	local success,errormessage = pcall(function()
		DataStore2:SetAsync("tools-"..plr.UserId,tools)
	end)
	
	if success then
		print("Tools data was successfully saved")
	else
		print("An error occured: "..errormessage)
	end
	
	local success,errormessage = pcall(function()
		DataStore2:SetAsync("equipped-"..plr.UserId,plr.Equipped.Value)
	end)
	
	if success then
		print("Equipped data was successfully saved")
	else
		print("An error occured: "..errormessage)
	end
end)
2 Likes

In the DataStore2 module, you don’t need to save in PlayerRemoving. It does that for you. Also, SetAsync isn’t a function (I think) in DataStore2, that’s your issue.

Yes, I was scripting slightly differently from AlvinBlox because he was using DataStore, and I was using DataStore2 - but I didn’t realize that PlayerRemoving wasn’t needed for DataStore2, although it makes sense.

So I should just remove the entire function altogether?

DataStore2 doesn’t have the function called SetAsync. Instead it has the functions :Set() and :Increment(). If you want to fix this switch to DataStore since it does have the :SetAsync() function. Just remember that data losses may occur more likely with DataStore than DataStore2

You’re using :SetAsync() which is used for DataStoreService, not for Datastore2, Go check a tutorial for Datastore2 :slight_smile:

I think the reason why you are getting this error is because you are using DataStore2 wrong and using it like normal data stores.

DataStore2 saves data a little differently to normal data stores. For example with DataStore2 you don’t need to save data when the player leaves the game but instead save the players data whenever it changes. You also don’t need to worry about putting all your data store requests in pcalls because DataStore2 handles all this stuff internally.

The reason why people use DataStore2 is because it prevents data loss. You don’t need to worry about data store limits because your data is cached meaning you can call the saving method as many times as you want. If you want to read more about DataStore2 I would visit the documentation page: DataStore2. You may also find it useful to visit the main community tutorial thread as well for DataStore2:
How to use DataStore2 - Data Store caching and data loss prevention

Here is a quick example of how to use DataStore2:

local DataStore2 = require(script.Parent.DataStore2)

DataStore2.Combine("DATA", "Coins") -- Combines all your data under one key

game.Players.PlayerAdded:Connect(function(Player)
	local CoinsStore = DataStore2("Coins", Player)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	local Coins = Instance.new("NumberValue")
	Coins.Name = "Coins"
	Coins.Value = CoinsStore:Get(0)
	Coins.Parent = leaderstats
	
	CoinsStore:OnUpdate(function(NewCoins)
		Coins.Value = NewCoins
	end)
	
	leaderstats.Parent = Player
	
	while wait(2) do
		CoinsStore:Increment(1)
	end
end)

As a side note you shouldn’t be using the DataStore2 model from the toolbox because it is outdated. Instead you should get the latest version from the releases page:

I know how to use DataStore2 (Except for what I just did…), but anyway, I have another problem, although I expect it to be because of the same reason. bad argument #3 to 'Value' (string expected, got table)

local equipped = Instance.new("StringValue")
	equipped.Name = "Equipped"
	equipped.Parent = plr

	local function equippedUpdate(updatedValue)
		equipped.Value = equippedDataStore:Get(updatedValue)
	end
	
	equippedUpdate(equipped.Value)
	equippedDataStore:OnUpdate(equippedUpdate)
	
	if equippedDataStore ~= nil then
		equipped.Value = equippedDataStore
	end

This error is happening because you are trying to set the value of the ‘equipped’ StringValue to a table (DataStore2 DataStore object). If you want the value of the DataStore, use it’s :Get() method:

if equippedDataStore ~= nil then
	equipped.Value = equippedDataStore:Get() -- Inside this bracket put the default value, (false for example)
end

I forgot to mention, he has a DataStore2 tutorial. It will suit you far better, it’s even mentioned on the devforum post!