Datastore losing data for some reason

I want to save data to a datastore

I am losing data for some reason.

I can not find any solution so far. I already looked for more solutions.

Block of code that is giving trouble:
(top is data that is going to be saved, bottom is data printed from the datastore)
I lost [“owned”] value for some reason.

player:WaitForChild("leaderstats").Money.Value -= totalPrice
					
data[targetSlot].owned = true

print(data)

dataStore:SetAsync(player.UserId, data)

task.wait(5)
					
local newData = dataStore:GetAsync(player.UserId)
					
print(newData)	
4 Likes

What is targetSlot and what is its value normally?

1 Like

It stores transforms for objects.

1 Like

Are you using the Roblox DataStoreService?

Because I don’t see any issues with this other than it possibly being slow or your API Services being disabled in the game settings.

Any errors within the output?

1 Like

No errors and API services are enabled.

1 Like

This is the mixed array issue. If you put numerical indices (starting from 1) and keys in a table, the way it gets handled on the background changes. You can just convert numerical indices to strings and see all keys stored.

Example:

local data = {
    [1] = "A",
    ["O"] = "B",
}

local newTab = {}

for i, val in data do
    local key = i
    if type(i) == "number" then
        key = tostring(i)
    end
    newTab[key] = val
end

print(newTab) -- { ["1"] = "A", ["0"] = "B" }
2 Likes

let me change things around and I will get back to you

1 Like
local data = {
    [1] = "A",
    ["O"] = "B",
}

local newTab = {}

for i, val in data do -- Shouldnt this be for i, val in pairs(data) do?
    local key = i
    if type(i) == "number" then
        key = tostring(i)
    end
    newTab[key] = val
end

print(newTab) -- { ["1"] = "A", ["0"] = "B" }

When you pass tables across Roblox’s internal implementations (such as the one you are having issue with, datastores, and RemoteEvents) the tables go through a process that rearranges the table. If the entire table is an array, it’s ordered in integers starting from 1 (indices start from 1 in Lua). You can also have dictionaries with keys, therefore strings. If you mix up both numerical and string indices, it becomes a mixed array. Roblox handles it so that keys get removed if you put numerical indices (should start from 1 again).

1 Like

In Vanilla Lua, yeah, you should use pairs(). But thanks to Luau, you can iterate through the table without using it.

1 Like

To make it simple: roblox just deletes string indices if the array is already contains number indices?

1 Like

You could also just convert the table to JSON and then compress that string, killing two birds with one stone. Once you retrieve the data, decompress it then JSONDecode it. This also saves you the trouble of converting indices to strings. (Also if you have a string variant of a numerical index already in the table for some reason e.g. “1” & 1)

1 Like

Yes but this is only valid for datastores and RemoteEvents, you could mix up tables in your scripts.

1 Like

This seems like the best course of action, thank you. (testing it now)

1 Like

Anytime, if you need assistance with anything just let me know.

1 Like

Okay so for some reason when I load the data from the datastore after JSON encoding it it is empty without any elements.

1 Like

It doesn’t say so. Could you show me how you could get it done with it, please?

1 Like

(original post removed by author)
Edit: nvm, you were completely right I can’t believe I overlooked JSON not support mixed tables.

1 Like

I am dead tired rn so I will get back to you guys tomorrow, thanks for the help so far!

1 Like

Would making a second datastore that just stores strings work as well? I know it probably is not the best solution, but it will be a easy fix and would require less code than other solutions.