Value that is clearly in table, keeps returning false?

I am trying to datastore a table of owned pets for players, but every time a code is redeemed, it does not seem to detect that the entry is in the table, even though it is CLEARLY there as I have printed all the items that are in the table and it is in there about five times now.

local function CheckCode(Player, Code)
	if(Codes[Code])then
		local Inventory = InventoryStore:GetAsync(Player.UserId.."_Inventory")
			if Inventory[Codes[Code][2]] then 
				return "Already Used"
			else
				table.insert(Inventory, tostring(Codes[Code][2]))
				InventoryStore:SetAsync(Player.UserId.."_Inventory", Inventory)
				return "Redeemed"
			end
		else
			return "Invalid Code"
	end
end

I do not understand what I am doing wrong, and this is pushing me to the edge of sanity, all help is appreciated.

5 Likes

Can we see your Inventory variable’s array structure? I am perplexed by what you are doing with it, and I may be able to understand more if I can see what the Inventory table represents in its entirety.

1 Like

Just as @chasedig1 said we need to understand your variables array structure. I can tell you something though, never use SetAsync when updating a players inventory (Stop using SetAsync() to save player data)

2 Likes

Sure, here you go.

local HTTP = game:GetService("HttpService")
-- Censored for reasons
local Codes = HTTP:JSONDecode(CodeStore)
local DSS = game:GetService("DataStoreService")
local InventoryStore = DSS:GetDataStore("Inventory")
local CodeEvent = game.ReplicatedStorage.CodeEvent
local CodeFunction = game.ReplicatedStorage.CodeFunction
local StarterInventory = {"Starter1","Starter2"}

game.Players.PlayerAdded:Connect(function(Player)
	local UserData
	pcall(function() 
		UserData = InventoryStore:GetAsync(Player.UserId.."_Inventory")
	end)
	if UserData == nil then
		InventoryStore:SetAsync(Player.UserId.."_Inventory",StarterInventory)	
	end
end)
1 Like

You are only inserting the value of Codes[Code][2] into inventory. You are then trying to receive that value, which is much lower down the array tree, which IS nil, because Inventory has been set to, not Inventory[Codes[Code][2]], which you are checking for.

Edit: To be more specific, you are inserting the value of a variable you JSONDecoded earlier, into the bottom level of the array. You are trying to access a value that is a few layers down with your if statement:

1 Like

I don’t work with tables much (correct me if im wrong) but I believe it’s because you’re doing Codes[Code] and Code is the actual code not a number like 1 (which will find the first entry in the table). Try table.find()

1. local t = {"a", "b", "c", "d", "e"}
2. print(table.find(t, "d")) --> 4
3. print(table.find(t, "z")) --> nil, because z is not in the table
4. print(table.find(t, "b", 3)) --> nil, because b appears before index 3
1 Like

When I insert this value it shows up in the table as one of the entries after the async is set, which is why I am confused unto why the second time it is called, it is still nil. I am sorry if you explained this already, my brain is quite dead right now as it is three in the morning.

Also, Codes[Code] does work, what it is doing is looking for an entry that is equal to the value provided.

1 Like

I did something similar to this yesterday and found I had to use table.find strangely enough that’s why I assumed this is what was happening.

Codes[Code] doesn’t work. It is looking for an entry INSIDE the table at and index that doesn’t exist, and checking that the nonexistent index exists, which it doesn’t, as it is nil.

You inserted a string converted value into the main layer of the table, which has no depth or object properties. Try replacing your table.insert statement with:

table.insert(Inventory[Codes[Code][2]], tostring(Codes[Code][2]))

I think it should work in that case.
If it doesn’t, try this other one:

table.insert(Inventory, Codes[Code][2])
1 Like

Just to check this would also work with string.find(Codes,Code) right but it would return the entry number?

Tables havent been my strong point :laughing:

1 Like

Usually, when dealing with deep, confusing arrays, I just tend to just use normal syntax with the brackets. That wouldn’t work because Codes, is just a link to his webserver, containing every code in the game. We’re checking if he already used the code, not if it exists!

2 Likes

I think I explained my problem incorrectly, it is not Codes[Code] that is causing the error.

This is not detecting that the code has already been redeemed, even though it has been redeemed already. Codes[Code][2] is equal to "Dog"

When printing the contents of Inventory using:

for i,v in pairs(Inventory) do
print(v)
end

Dog x5 is returned.

Which is why I am confused to why not even Inventory[“Dog”] will throw a true statement.

1 Like

With your for loop, try printing i AND v, then tell me what they both are.

1 Like

image

1 Like

Inventory[“Dog”] won’t return a true statement because that is the value, not the index, silly!

The indexes are 1, 2, 3, and so on. Actually, now knowing what your goal is, @MineDevs was right to use table.find()! To find an index with a certain value in it within a table, use this:

table.find(Inventory, “Dog”) to find what index dog is.

5 Likes

Ok that makes me feel much better about what I was trying to say, sorry if I was unclear :laughing::+1:

2 Likes

Well, you learn something everyday, I just wish I posted earlier to save myself almost smashing my keyboard a couple times. :slight_smile:

Sorry to ask, but please mark my solution as correct if it solved your problem. :slight_smile:

Edit: Thank you! Enjoy your the rest of your day/night!