Inserting a new table into a current table

This function fires whenever a player collects an item

ItemCollected.OnServerEvent:Connect(function(player, item)
	local User = PlayerData[player.UserId]
	if not User then return end
	
	-- Check if the table is already in their backpack
	for i, v in pairs(User.Backpack) do
		if i == item then
			v = v + 1
			DataUpdated:FireClient(player, User)
			return
		end
	end
	
	-- New item, so need to create new table
	local NewItem = {item = 1}
	table.insert(User.Backpack, NewItem)
	
	DataUpdated:FireClient(player, User)
end)

Now, by default the players backpack is

User.Backpack = {}

And how it my function works is it checks your backpack to see if you already have that item there, if not then it creates a new item and sets its value to 1, so if you collect a piece of wood it should look like this:

User.Backpack = {
    Wood = 1
}

Collect steel, it’ll check, see that steel isn’t in your backpack, so create steel

User.Backpack = {
    Wood = 1,
    Steel = 1
}

Now if you collect another piece of wood, it should see that you already have wood created in your backpack, so instead of going

User.Backpack = {
    Wood = 1,
    Steel = 1,
    Wood = 1
}

It should go

User.Backpack = {
    Wood = 2,
    Steel = 1

I’m not getting any errors however I don’t believe it’s not adding new items properly, as if I go

for i, v in pairs(User.Backpack) do
	print(i, v)
end

It should print Wood 2, Steel 1, but instead prints 1 table

1 Like

The way you’re using table.insert, you’re inserting the item table INSIDE another table, as so:

Backpack = {{NewItem = 1}} -- one entry and its a table

Instead, try doing something like:

Backpack[NewItem] = 1

2 Likes

The reason why it’s printing a table is because your inserting a table into the User.Backpack if the item does not exist within the backpack.

You can simply fix this by setting it like such:
User.Backpack[Item] = 1

If the item already exists within the backpack, you can just add one to the already exisiting index.
User.Backpack[Item] = User.Backpack[Item] + 1

I wrote up an example can show you the rough idea:

local User = {
	Backpack = {
		Wood = 3
	}	
}

local function ItemCollected(Item)
	for Object, _ in pairs(User.Backpack) do
		if Object == Item then
			User.Backpack[Item] = User.Backpack[Item] + 1
			return
		end
	end
	User.Backpack[Item] = 1
	-- Rest of code.
end
ItemCollected("Wood")

for Object, Amount in pairs(User.Backpack) do
	print(Object, Amount)
end
-- Prints: Wood 4


Idk hows it storing that data, but then I can’t send the data to the client

User.Backpack[item] = 1
DataUpdated:FireClient(player, User)

Get this error
Cannot convert mixed or non-array tables: keys must be strings

A bandaid fix could be using a for loop and individually sending the item and value through the event, and modifying the code clientside, however, it wont be sent all at once and may cost several calls.

I apologize for not giving code example, but I cant do much on mobile. I hope other people can help out though.

I get the same problem as using the other answers code

1 Like

Strange, I can’t seem to reproduce that. On my end, sending User through the remote is working fine.
You might want to double check how the keys within User is being set up.

You can also try to send through User.Backpack instead and see if you get the same result or not.

This post might be helpful:
link here

My key is just my players user ID
If I do this

ItemCollected.OnServerEvent:Connect(function(player, item)
	local User = PlayerData[player.UserId]
	if not User then return end
	
	for Object, _ in pairs(User.Backpack) do
		if Object == item then
			User.Backpack[item] = User.Backpack[item] + 1
			return
		end
	end
	
	User.Backpack[item] = 1

	for i, v in pairs(User.Backpack) do
		print(i, v)
	end
end)

It prints NinjoOnline 1, which it shouldn’t. Should be Wood 1

The only reason it’d print [NinjoOnline 1] (from what I can see at least), is because item is NinjoOnline. The player argument is passed by default, so you are probably doing something along the lines of ItemCollected:FireServer(player, item) instead of ItemCollected:FireServer(item) ??