[SOLVED] Can't Return Values..?

So I’m working on making private servers for players to use for testing, or just playing with small-groups of players. Kind of like a Roblox VIP server…but not…makes sense right?

Anyway, doing this I wanted to integrate it with my database so players can have the same server and customize it how they want. So, I would need to get the data from the database to the client so they can change the settings they have saved, or let them know that they don’t have a server and they should totally make one because they’re super cool. (Invoking the Server)

The problem is: I cannot return values from the Database, it works like this:

myDatabase:GetAsync("Private_Servers","Code", function(Success, Value, ServerResponse)
       if not Success then
            return "DB_ERROR"
       elseif Value.Value then -- if there is no value in the DB
            return "NO_SERVER"
       else
            return game.HttpService:JSONDecode(Value.Value.value)
       end
end)

I have no idea where those strings (or the table) goes because it doesn’t go to the LocalScript because it famously prints nil when trying to print the result of the invoke.

I’ve tried a lot of tricks I thought to do, all with no success:

  • Setting a local value to the value to return, then return it after the DB function is done.
  • Adding the values to a table, then returning the table.
  • Setting a StringValue to the return value, then passing the value after the DB function is done.

The only thing I was able to do with some success is firing an event to the client with the data I received, but this seems unsustainable to me, would cause me to get all sorts of confused.

I’m looking for a way to pass values back to the client without having to fire events to the client. If this is the only, please also let me know and I’ll just deal with it.

2 Likes

This is the first error that I see. You aren’t closing the function with a close parentheses. I also believe that you’d need another end for the callback.

Please correct me if I’m wrong - this entire GetAsync() function is located in a OnServerInvoke, correct?

1 Like

Correct. Also, I am closing that in the code…just a typeo here

What is the expected value of just Value, Value.Value, and Value.Value.Value?

Value is the complete array that my database returns. (Success, error, and Value)
Value.Value is the key and value of that key. (key and value)
Value.Value.value is the value of the request.

Hey, could you provide how you are storing / saving this Data?

Can you send an example of the entire Value, including the success, error, and everything that would be contained in the Value? Would it be a JSON array (that would have to be JSONDecoded)?

From what you’re describing to me, it seems to me like accessing Value.Value.Value would have to be Value[PositionNumber][Key].Value but I cannot confirmed without getting more information on it.

Sure, here ya go. (I don’t have any private servers saved yet, so I’ll send you a different table, it’s the same idea though.)

{"Success":true,"ValueExists":true,"Value":{"key":"172976679","value":{"code":"12345","active":true}}

It’s a web-based database. (30303030)

Have you tried JSONDecoding it right off the bat before anything else happens? Value = HTTPService:JSONDecode(Value)

I can’t even get the values out of the function. I can do anything to them in the function, but I can’t get anything out of it.

From what you’re describing to me,

This entire thing is still in pure JSON and has not yet been decoded. If it is not decoded, then you will not be able to access its values here:

or here:

You must decode the JSON value first before anything else happens so that you can properly check the values.

Try this:

myDatabase:GetAsync("Private_Servers","Code", function(Success, Value, ServerResponse)
       Value = game:GetService("HttpService"):JSONDecode(Value)
       if not Success then
            return "DB_ERROR"
       elseif Value.Value then -- if there is no value in the DB
            return "NO_SERVER"
       else
            return Value.Value.value
       end
end)

Nope…still returning nil. (30303030)

Are you able to print the error messages once they have been returned by this function?

There are no errors, it works fine inside of the function.

I’m taking about these errors

Are you able to print them once they have been returned from this function?

EDIT:
Could you also provide the code which runs the function argument for the GetAsync call?

Nope, I can’t print those either.

Here’s the code:

function sql:GetAsync(Table, Key, Callback)
	if (Table == nil) then
		return error("Table is unspecified", 0);
	elseif (Key == nil) then
		return error("Key is unspecified", 0);
	elseif (Callback == nil) then
		return error("Callback is unspecified", 0);
	end
	
	spawn(function()
		local data = http:RequestAsync({
			Url = sql.ApiUrl .. "/getAsync",
			Method = "POST",
			Headers = {
				ApiToken = sql.Token,
				["Content-Type"] = "application/json"
			},
			Body = http:JSONEncode{
				Key = Key,
				Table = Table
			}
		})
		local validJson, Resp = pcall(function()
			return http:JSONDecode(data.Body);
		end)
		if (validJson) then
			if (data.StatusCode == 200) then
				Callback(true, Resp);
			else
				Callback(false, "Request did not succeed. [" .. data.StatusCode .. "]", Resp);
			end
		else
			Callback(false, "Server returned invalid response", data.Body);
		end
	end)
end

When the http request succeeds as expected, the second argument in the callback function will be the JSON Decoded result.

The rest of the callback calls are for when the request has failed or when the response is not a valid JSON.

In the GetAsync code you are using spawn, which queues a new lua thread to the task scheduler, meaning it will run asynchronously with other threads. I suggest removing this.

If you are trying to run:

print(myDatabase:GetAsync(...))

I also suggest you return the calling of the callback function where you currently just call it, like so:

-- Current (only calls the callback function, doesn't use any of its returned values):
Callback(true, Resp);
-- Suggested (returns calling of the callback function, meaning it will return whatever the callback function returns):
return Callback(true, Resp);

However, this won’t change much unless the spawn is removed as you can’t return values from inside a spawn function. returning callback and removing the use of spawn will allow you to run the print statement above and it will print the returning value from the callback.

EDIT - I removed spawn and added return to the callback calls for you, you might want to give this a test since I edited it here:

function sql:GetAsync(Table, Key, Callback)
	if (Table == nil) then
		return error("Table is unspecified", 0);
	elseif (Key == nil) then
		return error("Key is unspecified", 0);
	elseif (Callback == nil) then
		return error("Callback is unspecified", 0);
	end
	
	local data = http:RequestAsync({
		Url = sql.ApiUrl .. "/getAsync",
		Method = "POST",
		Headers = {
			ApiToken = sql.Token,
			["Content-Type"] = "application/json"
		},
		Body = http:JSONEncode{
			Key = Key,
			Table = Table
		}
	})
	local validJson, Resp = pcall(function()
		return http:JSONDecode(data.Body);
	end)
	if (validJson) then
		if (data.StatusCode == 200) then
			return Callback(true, Resp);
		else
			return Callback(false, "Request did not succeed. [" .. data.StatusCode .. "]", Resp);
		end
	else
		return Callback(false, "Server returned invalid response", data.Body);
	end
end

I’ll give it a go, just a second. :happy1:

Got an error -

Line 112, 113 and 114.

if (validJson) then
		if (data.StatusCode == 200) then
			return Callback(true, Resp);

What is on the other lines shown in the stack trace? The error might not be caused by Line 114 of the Database module

EDIT:

It could be this line causing the issue in the callback function you have provided, because the response from the API is already JSONDecoded before being sent to the callback function:

return game.HttpService:JSONDecode(Value.Value.value)