Getting dictionary name as a string?

I am trying to use the key of a dictionary as a string for checking the DataStore entry of the same key name, but I cant seem to get the keys name to work as a string. When i print the keys name, i get the name printed out fine, but when i try to use it in a reference to that DataStore key, i get an error that says:

[Bad argument #1 to SaveData::Get() (string expected)]

Here is the code:

--// Recipes: we currently only have one recipe,
local recipes = {

Tacos = {
	Lettuce = 1, 
	Shells = 1, 
	Cheese = 1, 
	Meat = 1}
}

function tycoonTools.cookTacos(player)
    local currentRecipe = recipes.Tacos
    local saveData = PlayerDataStore:GetSaveData(player)
    local checkRecipe = {}
    for i,v in pairs (currentRecipe) do
	print(i)
	local currentValue = saveData:Get(i)
	if currentValue >= v then
		checkRecipe[i] = true
	else checkRecipe[i] = false
	end
end

So whats it trying to do is match the value in saveData and compare it to the value of currentRecipe and if that value od currentRecipe is greater than or equal to the one in saveData, it will set a value of true in the table checkRecipe.

The keys in the saveData table match the keys in the currentRecipes table but I get the error on this line:

local currentValue = saveData:Get(i)

I guess it needs a string and i have tried things like tostring but i cant get it to work.

What am i doing wrong here? Thanks!

EDITS: cleanign up the code

Is PlayerDataStore:GetSaveData(player) a custom function of yours?

1 Like

its a modified version of Stravants DataStore. this method works fine in other uses in my game so far

Try doing print(type(i)), if it shows string then you should be fine, if it shows anything else but that you can try using tostring(i) instead of just doing i.

1 Like

they do in fact show as strings when printed in this way

It’s very likely an issue with the :Get() method, so it’d help if you could post that. Also if possible it’d help if you print the result of type() from the arguments Get receives.

1 Like

I’m having a hard time finding the exact method inside the DataStore script because I didn’t make it, I will keep looking.

However, I have the same method workign in another function just fine:

function scoreTools.addDataScore(player,name,value)
	local saveData = PlayerDataStore:GetSaveData(player)
	local currentCount = saveData:Get(name)
	if not currentCount then
		currentCount = 0
	end
	currentCount = currentCount + value
	saveData:Set(name,currentCount)
end

found it:

-- Getter and setter function to manipulate keys
-- for this player.

function this:Get(key)
me.debugPrint("(".. this.userId .. ") GETTING " .. tostring(key));
if type(key) ~= 'string' then
error("Bad argument #1 to SaveData::Get() (string expected)", 2)
end
if DEBUG then
print("SaveData<"..this.userId..">::Get("..key..")")
end
markAsTouched(key)
local value = this.dataSet[key]
if value == nil and DESERIALIZE[key] then
-- If there's no current value, and the key
-- has serialization, then we should get the
-- null deserialized state.
local v = DESERIALIZE[key](nil)
-- Note: we don't markAsDirty here, that's
-- intentional, as we don't want to save
-- if we don't have to, and we don't need
-- to here, as Deserialize(key, nil) should
-- return back the same thing every time.
-- However, we still need cache the value,
-- because deserialize(key, nil) might still
-- be expensive or the caller might expect
-- the same reference back each time.
this.dataSet[key] = v
return v
else
return value
end
end
2 Likes

The problem here is that you aren’t iterating through your table properly.

You should be using using “in next,” to iterate through the keys and values properly:

for key, value in next, currentRecipe do
	print(key, value)
end
2 Likes
function this:Get(key)
me.debugPrint("(".. this.userId .. ") GETTING " .. tostring(key));
if type(key) ~= 'string' then

in that bit, add one line;

function this:Get(key)
print(key,type(key))
me.debugPrint("(".. this.userId .. ") GETTING " .. tostring(key));
if type(key) ~= 'string' then
1 Like

the ‘pairs’ function already returns next among other arguments.

pairs (t)

Returns three values: the next function, the table t , and nil , so that the construction

for k,v in pairs(t) do body end

will iterate over all key–value pairs of table t .

from https://www.lua.org/manual/5.1/manual.html#pdf-pairs

4 Likes

Ahh, you’re right. For some reason that used to not work for me before. :thinking:

1 Like

I mean personally I prefer next since I’m used to it, but thats just a personal preference.

2 Likes

Although I am not sure if it’s any help, from the example you gave it does seem like you’re missing an “end” to close the scope. For the loop or function it seems. Other than that it should work, it works when I try it in a basic test setup.

1 Like