Datastore "no pages to advance to" error

So uhhhhhhh, i’ve decided to finally start working with datastores!

the problem is, i have no idea what i’m doing and i don’t know how to fix the error that’s in the title
i know exactly why it happens, but i don’t know how to fix it

this is how my datastore works

  • Player sends some feedback via remote event
  • Server checks that feedback, if it’s valid then it adds the feedback into an ordered datastore
  • Server runs some space-alien code that loops through the current page and repeats to do so until it doesn’t advance to another one (this is extrreeemely stupid to do because as of right now there is no feedback at all)

normally you would say “why have that in a repeat loop??”
well to that i say; “what if there are multiple pages”?

note that this is my first time with datastores so please be patient D:

code:

local dStoreService = game:GetService("DataStoreService")

local feedbackData = dStoreService:GetOrderedDataStore("FeedbackData")

function GetAllFeedback()
	local feedbackList = {}

	local success, pages = pcall(function()
		return feedbackData:GetSortedAsync(false, 100)
	end)

	if success then
		repeat
			local currentPage = pages:GetCurrentPage()

			for _, entry in ipairs(currentPage) do
				local feedback = feedbackData:GetAsync(entry.key .. "_data")
				
				if feedback then
					table.insert(feedbackList, feedback)
				end
			end
			
		until not pages:AdvanceToNextPageAsync()
		
		return feedbackList
	else
		warn(pages)
	end
end

local allFeedback = GetAllFeedback()

if allFeedback then
	for _, feedback in ipairs(allFeedback) do
		print("Player ID: " .. feedback.Player)
		print("Topic: " .. feedback.Topic)
		print("Elaboration: " .. feedback.Elaboration)
		print("Timestamp: " .. os.date("%Y-%m-%d %H:%M:%S", feedback.Timestamp))
		print("-----")
	end
end
2 Likes

Try wrapping the AdvanceToNextPageAsync() in another pcall? Probably not the best solution but it’s quick.

1 Like

didn’t work, unfortunately

sending over the updated code;

function GetAllFeedback()
	local feedbackList = {}

	local success, pages = pcall(function()
		return feedbackData:GetSortedAsync(false, 100)
	end)

	if success then
		repeat
			local currentPage = pages:GetCurrentPage()

			for _, entry in ipairs(currentPage) do
				local feedback = feedbackData:GetAsync(entry.key .. "_data")
				
				if feedback then
					table.insert(feedbackList, feedback)
				end
			end
			
			local advanceSuccess, nextPage = pcall(function()
				return pages:AdvanceToNextPageAsync()
			end)
			
			if not advanceSuccess or not nextPage then
				break
			end
			
		until false
		
		return feedbackList
	else
		warn(pages)
	end
end
1 Like

I’ve not messed around with datastores much but I found this sample while looking through the documentation.
So in your case the code would look like:

	if success then
		while true do
			local currentPage = pages:GetCurrentPage()
			for _,entry in ipairs(page) do
				local feedback = feedbackData:GetAsync(entry.key .. "_data")
				if feedback then
					table.insert(results,feedback)
				end
			end
			if pages.IsFinished then break end
			pages:AdvanceToNextPageAsync()
		end
		
		return feedbackList
	else
		warn(pages)
	end
1 Like

yeah that’s kind of exactly what i just did right now, the code works but uhhh

image

image


WHICH ONE IS IT THEN???

IS THIS NOT A DICTIONARY???

local key = "Feedback_" .. plr.UserId .. "_" .. os.time()
	local timestamp = os.time()
	
	local success, result = pcall(function()
		feedbackData:SetAsync(key, timestamp)
		feedbackData:SetAsync(
			key, 
			{Player = plr.UserId,
				Topic = topic,
				Elaboration = elaboration,
				TimeSent = timestamp
			}
		)
	end)
	
	if success then
		print("Feedback received successfully!")
		
		plr:SetAttribute("FeedbackCooldown", true)
		coroutine.wrap(function()
			task.wait(300)
			plr:SetAttribute("FeedbackCooldown", false)
		end)()
	else
		warn("Failed to save feedback! " .. result)
	end

break the loop if DataStoreKeyPages.IsCompleted or something like that check docs

That is, infact, a dictionary.
Have you not tried using HTTPService:JSONEncode? That converts the array/dictionary into a string, which you can safely store inside a datastore.

2 Likes

edit = i didn’t see the wrapping {}, try httpservice json encode
you can’t set dictionary as data

hold on i’m attempting this rn, i’ll keep you updated

1 Like

If I recall correctly OrderedDataStores can only have one type of value stored in em, not strings, not tables, just numbers.
The key can be a string yes, but the data you are setting it to can only be a number.

If that isnt what the problem is please correct me lol

this is correct, i gave ordered data store the middle finger and went to regular datastores

it’s going quite nicely rn, painful, but nice

1 Like

@TestyLike3
@FroDev1002
@computerph1_DEV
(Yes i had to mention all 3 of you)

i think this is gonna work?


code that validates and sends feedback to the datastore:

local feedbackData = dStoreService:GetDataStore("FeedbackData")

function OnFeedbackReceived(plr: Player, topic: string, elaboration: string)
	if #elaboration > 200 then
		plr:Kick("I told you to shorten the character limit.")
		return
	end
	
	if elaboration == "" then
		plr:Kick("The elaboration can't be empty...")
		return
	end
	
	if topic == "" then
		plr:Kick("I won't view your feedback if you don't include a topic, bypassing won't help.")
		return
	end
	
	if #topic > 50 then
		plr:Kick("I told you to shorten the topic...")
		return
	end
	
	if plr:GetAttribute("FeedbackCooldown") then
		plr:Kick("Why are you trying to flood the feedback box?")
		return
	end
	
	local key = "Feedback_" .. plr.UserId .. "_" .. os.time()
	local timestamp = os.time()
	
	local feedbackDataTable = {
		Player = plr.UserId,
		Topic = topic,
		Elaboration = elaboration,
		TimeSent = timestamp
	}
	
	
	local success, result = pcall(function()
		feedbackData:SetAsync(key, feedbackDataTable)
	end)
	
	if success then
		print("Feedback received successfully!")
		
		plr:SetAttribute("FeedbackCooldown", true)
		coroutine.wrap(function()
			task.wait(300)
			plr:SetAttribute("FeedbackCooldown", false)
		end)()
	else
		warn("Failed to save feedback! " .. result)
	end
end

code that gets the feedback data

local feedbackData = dStoreService:GetDataStore("FeedbackData")

function GetAllFeedback()
	local feedbackList = {}
	
	local success, result = pcall(function()
		local pages = feedbackData:ListKeysAsync("Feedback_")
		
		while true do
			for _, entry in ipairs(pages) do
				local key = entry.key
				local feedback = feedbackData:GetAsync(key)
				
				if feedback then
					table.insert(feedbackList, feedback)
				end
			end
			
			if pages.IsFinished then
				break
			end
			
			pages:AdvanceToNextPageAsync()
		end
	end)
	
	if success then
		return feedbackList
	else
		wait("Failed to receive feedback list!" .. result)
		return nil
	end
end
2 Likes

Try running it yourself. I’d rather have an error to go off from instead of looking through all of the code, because that’s how I usually fix my bugs.

SORRY I WAS AFK

i tested it (in studio, scold me if that’s not what i’m supposed to do) and it gave no errors

HOWEVER;

this doesn’t print at all (i assume this is because there is no data found at all)

local allFeedback = GetAllFeedback()

if allFeedback then
	for _, feedback in ipairs(allFeedback) do
		print("Player ID: " .. feedback.Player)
		print("Topic: " .. feedback.Topic)
		print("Elaboration: " .. feedback.Elaboration)
		print("Timestamp: " .. os.date("%Y-%m-%d %H:%M:%S", feedback.Timestamp))
		print("-----")
	end
end
1 Like

… and you didn’t try printing allFeedback? That would’ve been my next idea before assuming it doesn’t exist. I’d also sprinkle print statements across the GetAllFeedback() function.

1 Like

allFeedback prints nil

here are some of the function prints:

function GetAllFeedback()
	local feedbackList = {}
	
	local success, result = pcall(function()
		local pages = feedbackData:ListKeysAsync("Feedback_")
		
		while true do
			print("a") -- prints
			for _, entry in ipairs(pages:GetCurrentPage()) do
				print("b") -- prints
				local key = entry.key
				local feedback = feedbackData:GetAsync(key)
				
				if feedback then
					table.insert(feedbackList, feedback)
					print("inserted lol") -- doesn't print for obvious reasons i think
				end
			end
			
			if pages.IsFinished then
				print("c") -- doesn't print (not sure why?)
				break
			end
			
			pages:AdvanceToNextPageAsync()
		end
	end)
	
	if success then
		print("returning") -- doesn't print
		return feedbackList
	else
		wait("Failed to receive feedback list!" .. result)
		return nil
	end
end

local allFeedback = GetAllFeedback()

print(allFeedback)

idk if these are good results

I JUST REALISED I DID WAIT INSTEAD OF WARN LMAO

okay;

i had to do .KeyName instead of .Key, the function no longer prints nil! yay!

this is now fixed finally

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.