dataStore:GetOrderedDataStore not working?

Hello! I am currently creating a leaderboard for my game, but it seems to not quite work. I put in some prints, and all works until the “for rank,” repeat. Anyone know how to fix this? Here is my code:

local dataStore = game:GetService("DataStoreService")
local buckStore = dataStore:GetOrderedDataStore("Bucks")

local function leaderboard()
	local pages = buckStore:GetSortedAsync(false, 5)
	local topFive = pages:GetCurrentPage()
	
	for rank, data in pairs(topFive) do
		local name = data.Key
		print("test")
		local nameText = game.Players:GetNameFromUserIdAsync(name)
		script.Parent["Num".. rank].Name.Text = nameText
	end
end

leaderboard()
print("Thanks!")

I recommend watching this tutorial by @UseCode_Tap

2 Likes

Hey! I basically completely changed the post when I figured out the issue, but it’s just simply not getting data. The “for, rank” loop I have created refuses to run.

Are you saving any data to the datastore Bucks? If not, then the for loop will never run, as topFive is equal to nil

I am. Well, depends. Do dataStores save across game places? If so, then yes. I don’t see why this wouldn’t work. If not, then there’s my answer.

It will save across game places if they are in the same universe. How are you saving it to the datastore? Perhaps there is an error there?

By universe do you mean game? The data is saved in the place within the place where you actually play, whereas I am trying to receive this dataStore in the main menu place.

Yes, that is what i mean. Could you provide a copy of the code you use to save stuff to the data store Bucks?

Sure thing, it’s pretty simple as of right now.

game.Players.PlayerRemoving:Connect(function(player)
	local bucks = game.ReplicatedStorage.PlayerData["player".. player.UserId].Bucks.Value
	buckStore:SetAsync(player.UserId, bucks)

Within the actual game it works fine, as my entire shop relies on it and I have yet to see any issues with the shop.

EDIT: Oh, I forgot to add the actual datastore part of it:

local buckStore = dataStore:GetDataStore("Bucks")

It is actually an issue with dataStore:GetOrderedDataStore, as buckStore:GetAsync() works fine.

It’s not a problem with GetOrderedDataStore because that just returns an OrderedDataStore object, it’s your code. Specifically, because you spelled key with a capital K. You should’ve been getting errors in your console, which it doesn’t look like you checked either and if you did, haven’t specified what’s there.

Your answers could have been found by referring to documentation: this is the first thing that you should’ve done before posting a thread, moreso if your code came from the sample here. Answers are more often found by searching first and debugging second.

A very easy debugging method you could’ve hopped to first was to actually print what was in each iteration. If you had a table, then you could iterate through that. You could also use a resource to facilitate this, such as Repr, for complex or unknown tables.

for rank, data in pairs(topFive) do
    print(rank, data) -- This

GetSortedAsync returns a DataStorePages object. Each page is represented as an array of tables and each entry has two keys: key and value. Lua is case sensitive: you are writing out Key, not key.

NOW: If you can confirm that the for loop is NOT running, which you have not yet and can do so by adding the test print above the name declaration instead of below, then you have a different problem which is that your page is empty, so ignore everything above and look towards tackling that. That being said, this scenario can’t be possible unless there’s no data to be pulled at all, because OrderedDataStores do not accept non-integer values.

1 Like

I did indeed prove that the loop isn’t running. I created a print(“LoopWorks”) for debugging before I specified data.key and nothing was outputted in console. I probably should have mentioned that in an earlier comment.
I should also mention that I did check console, and nothing popped up. Would this perhaps be a good time to use pcall() for a debugging check or does pcall() not work in this situation?

If you added a print right below the for loop and nothing else as I showed in my sample, then there’s nothing to iterate over, meaning you have no data in your DataStore.

To check in: I don’t know where exactly you save data from because that code is not included, but do you also use GetOrderedDataStore for that? If not, change that and try again. All cases of DataStores related to “Bucks” need to be fetched via GetOrderedDataStore: one can’t be GetDataStore and another GetOrderedDataStore.

As far as I know, they’re held in separate namespaces.

1 Like

I used GetDataStore in a seperate place within my game/universe, and it does work fine. Let me try creating a seperate dataStore and use is solely for the leaderboard and see if that helps.

Yes that’s because when you save to the data store, the object you’re calling SetAsync on is also a GlobalDataStore, not an OrderedDataStore. I’m still making this assumption because I have no idea how you’re saving or if there’s any differences in any of your code working with the Bucks store (e.g. one script uses GetDataStore(“Bucks”) and some others use GetOrderedDataStore(“Bucks”)).

After you mentioned that and I went scrolling through the API, I noticed GetGlobalDataStore, whereas I am only using GetDataStore. Perhaps that could warrant what’s going on?
Also, here is all code involved in this “Bucks” DataStore:

Note these are snippets from seperate places of code, and are all from a seperate place then where my leaderboard currently is. The leaderboard is in my main place, and all of this code is within the place where the actual “game” is.

-- Defining the dataStore
local buckStore = dataStore:GetDataStore("Bucks")
-- OnPlayerAdded
local bucks = buckStore:GetAsync(player.UserId)
-- Player Leaving
local bucks = game.ReplicatedStorage.PlayerData["player".. player.UserId].Bucks.Value
buckStore:SetAsync(player.UserId, bucks)

I’ve mentioned this in all my posts so far: any cases of GetDataStore with the Bucks DataStore, change it to GetOrderedDataStore.

3 Likes

There we go, thank you, that (sort of) worked.
The reason I couldn’t change “Bucks” to GetOrderedDataStore was because of how bucks was being used. It was also the primary part of my in-game shop, which if I am correct using it as a regular value with no intention of ordering it should simply be GetDataStore. This was fixed though by creating a new dataStore named “Leaderboard” and placing the same data within it, and using GetOrderedDataStore.

print("Thanks for your help!")

OrderedDataStores have the same functions as GlobalDataStores. Provided you are only saving positive integer values to that DataStore, you can just use GetOrderedDataStore in all cases of needing to interact with the Bucks DataStore.

When needing a leaderboard made, use GetSortedAsync and co. If you’re just concerned with the value, GetAsync. OrderedDataStores have the same functionalities as non-ordered DataStores specifically so you can have that versatility available without doubling up DataStores where not necessary. In your case, because it’s just one DataStore with one value, no need to use two.

local DataStoreService = game:GetService("DataStoreService")

-- In all cases of needing to get the store
local BucksStore = DataStoreService:GetOrderedDataStore("Bucks")

-- In all cases of just needing a single value:
BucksStore:GetAsync(player.UserId)

-- In all cases of having to create an ordered leaderboard:
BucksStore:GetSortedAsync(args)
1 Like

Oh, I see now. Either way, I’m going to need 2 anyways since I am only using “Bucks” as a placeholder value until I get the dataStore that I really want for the Leaderboard up and running. Anyways, thanks for your help and patience! I’m still learning obviously.

1 Like

This post was really helpful, thanks!