Problem with a remoteFunction voiding it's variable

Hello, devs! I’m sorry if this problem is really easy, I’ve tried a lot to fix it but it doesn’t work!

What do you want to achieve? For my upcoming game, there are going to be multiple jobs the player can join.

What is the issue? In my script, I’m passing a variable via a remoteFunction. But when the variable is getting sent from the clinet to the server the variable value voids.

What solutions have you tried so far? I’ve rewritten the entire job system, I’ve deleted all the scripts and re-did the whole code. But it still doesn’t work.

local function process_JobRequest(player, requestedJob)
	local working = player:FindFirstChild("JobName")
	local success
	
	print("LINE 37  -  " .. requestedJob)
	
	if(working.Value == "" or working.Value == " ") then	
		
		if requestedJob.Value == "CafeJob" then
			working.Value = "CafeJob"
			player.TeamColor = BrickColor.new("Really red")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success
			
		elseif requestedJob.Value == "Sunset Cleaning" then
			working.Value = "SunsetCleaning"
			player.TeamColor = BrickColor.new("Dark green")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success
			
		elseif requestedJob.Value == "Sunset Lifeguard" then
			working.Value = "SunsetLifeguard"
			player.TeamColor = BrickColor.new("New Yeller")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success

		else
			print("ERROR Line 70 - " .. requestedJob)		

			success = false
			return success

		end
		
	else
		print("ERROR - " .. player.Name .. " is currently working at another job!")

		success = false
		return success
		
	end
	
end

request_JoinJob.OnServerInvoke = process_JobRequest

Server script, that is picking up the remoteFunction

joinBtn.Activated:Connect(function()
	joinJob_Close()

	local jobRequest = request_JoinJob:InvokeServer(requestedJob)

	if jobRequest == true then
		update_JobInfo(requestedJob)
		openInfo = true
		open_jobInfo()

		updateJobData:FireServer()

		local working = player:FindFirstChild("JobName")
		
		if working.Value == "CafeStaff" then
			
		elseif working.Value == "SunsetCleaning" then
			
		end
		
	elseif jobRequest == false then
		print("Picked up Server Error")

	end
end)

localScript where the remoteFunction is Invoked.

14:43:33.926 LINE 37 - NoJob - Server - JobHandler:37
14:43:33.926 ERROR Line 70 - NoJob - Server - JobHandler:72
14:43:33.953 Picked up Server Error - Client - JobGuisHandler:213
Output ^^

The Cafe Staff part works, but the Sunset Cleaning (Which is the exact same code, but a tiny bit different) doesn’t work! Thanks, in advance.

2 Likes

Might have to do with the fact that, for some reason, you’re spacing out your elseif statements which is completely different from elseif as one keyword. You should reformat your code with this in mind and see if it produces the same error, because beyond those elseifs the code looks fine.

Is the requestedJob a string? Also what is the requestedJob at the time you sent the InvokeServer?

Re-wrote the code, the same errors still pop up.

local function process_JobRequest(player, requestedJob)
	local working = player:FindFirstChild("JobName")
	local success
	
	print("LINE 37  -  " .. requestedJob)
	
	if(working.Value == "" or working.Value == " ") then	
		
		if requestedJob.Value == "CafeJob" then
			working.Value = "CafeJob"
			player.TeamColor = BrickColor.new("Really red")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success
			
		elseif requestedJob.Value == "Sunset Cleaning" then
			working.Value = "SunsetCleaning"
			player.TeamColor = BrickColor.new("Dark green")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success
			
		elseif requestedJob.Value == "Sunset Lifeguard" then
			working.Value = "SunsetLifeguard"
			player.TeamColor = BrickColor.new("New Yeller")
			success = true

			joinedJobModule.setup_Parameters(player)
			return success

		else
			print("ERROR Line 70 - " .. requestedJob)		

			success = false
			return success

		end
		
	else
		print("ERROR - " .. player.Name .. " is currently working at another job!")

		success = false
		return success
		
	end
	
end
1 Like

The code you’ve provided seems to be working as intended.

This says that requestedJob is the string “NoJob”

print("LINE 37  -  " .. requestedJob)
--> 14:43:33.926 LINE 37 - NoJob - Server - JobHandler:37

Now, let’s see what happens in the code.

if requestedJob == "Cafe Staff" then

requestedJob isn’t “Cafe Staff”, onto the next conditional

elseif requestedJob == "Sunset Cleaning" then

It’s not “Sunset Cleaning” either, onto the next conditional

else if requestedJob == "Sunset Lifeguard" then

Not “Sunset Lifeguard” either. Finally, we end up here:

else
	print("ERROR Line 70 - " .. requestedJob)

	success = false
	return success
end

You haven’t provided a condition for when requestedJob is “NoJob”, so it’s ending up at the “ERROR Line 70” print.

Yes, I am aware. But the value seems to be getting lost, when the client is invoking the server (Via remoteFunction) thus my error.

Yes requestedJob is a string, but when the client is invoking the server the value is seeming to be voided. I updated the code above, since I had to re-write the elseif. As someone said that could be a cause of my problem.

Well the code is running then, assuming your input on the example is NoJob at line 37, it should fail. Could you try to use other jobs that do exist?

1 Like

Is it supposed to be like this, with/without ‘.Value’?

Simply a string (idk, variable) or StringValue?

I was trying to see if .Value was needed, but it hasn’t fixed it. It’s just a string variable in a script,

When I try to join the cafe staff job it works. However any other job, just fails and I’m not sure if it’s a bugged script or something. (I’ve deleted and changed scripts) but nothing.

Have you tried adding a Breakpoint into the server side code and stepping through to see where your code lands?
You can also hover over variables while stepping through code to see what their values are.

There also seems to be inconsistency between your job titles
CafeJob != CafeStaff
Sunset Cleaning != SunsetCleaning

What is the variable (job?) you’re inputting from the client?

Hi!

I’m not sure what you are trying to do here, but it seems the value you are sending from the client is the string ‘NoJob’ (as indicated by the prints).

This string is not listed as the options, and so the server function returns false.

As intended, the localscript then says ‘picked up server error’. Despite all your custom messages, there seems to be no actual error… Perhaps try sending some other job names, such as ‘CafeJob’.

That said, there is a lot of duplicated code in here. Usually long lists of elseif statements have a better way to rewrite it in much less code. And instead of

if var == true then
  someFunction()
elseif var == false then
  someOtherFunction()
end

You can just

if var then
  someFunction()
else
  someOtherFunction()
end

An example of how to refactor (rewrite to do the same) your list of elseif statements (also known as a switch idiom):

local myJobs = {
  CafeJob = {WorkingValue = "CafeJob", Color = BrickColor.new("Really red")},
  ["Sunset Cleaning"]= {WorkingValue = "SunsetCleaning", Color = BrickColor.new("Dark green")},
  --etc
}

local function process_JobRequest(player, requestedJob)
	local working = player:FindFirstChild("JobName")
	local success
	
	print("Selected job : ", requestedJob)
	
	if(working.Value == "" or working.Value == " ") then
		local jobData = myJobs[requestedJob]
		if not jobData then return end
		working.Value = jobData.WorkingValue
		player.TeamColor = jobData.Color
		joinedJobModule.setup_Parameters(player)
		return true
	end
end

I didn’t test this code, may have typos. But the idea behind these changes is that it saves a lot of code, and it is easier to see the pattern when you come back later.

I noticed a repeating pattern, that had to be done the same with just some different values (the name and color that belong to a job). So I put those values in a table, and you can find them there using the jobname sent by the client as a key.

Notice: I advise using string without spaces for this, so you don’t have to use the inconvenient notation, as I did in the second item in the table:
[“Sunset Cleaning”]

Instead of returning ‘false’ we can just return nil, which also automatically happens at the end of a function (when nothing is explicitly returned using the return statement). In the localscript on the client we can just check:

if success then

And if success is nil, it counts the same as false.

A final small change is in your print statement: you use concatenation in this way:

print("LINE 37  -  " .. requestedJob)

This requires both sides to be a string. Suppose that requestedJob is nil sometimes, this would crash. Instead of the … to concatenate, I used simply a comma. This way, the text is sent as multiple separate arguments to print(). That way it is much less likely to crash, whatever goes in there. Usually we don’t want our prints to crash. When we want something to crash on purpose we can use

error("this crashes on purpose")

And if we want to print warnings in a fancy color we can use:

warn("Warning! this needs checking out!")

Hope this can be valuable to your future developing, you seem to be on the right track!

Hey, I updated my code using that idiom switch! It has worked, by the client is having a weird problem.

12:41:48.595 LINE 220 - SunsetCleaning - Client - JobGuisHandler:215
12:41:48.595 LINE 97 - SunsetCleaning - Client - JobGuisHandler:97
12:41:54.123 ERROR - Line 144 SunsetCleaning - Client - JobGuisHandler:138

However this is the code that is running:

local function joinJob_UpdateStats(player, jobName)
	print("LINE 97 - " .. jobName)
	
	local jobDataFolder = player:FindFirstChild("JobData")
	local currentWorking = player:FindFirstChild("JobName")

	if (currentWorking.Value == "" or currentWorking.Value == " ") then
		jobText.Text = "Join " .. jobName .. " job"
		
		if jobName.Value == "CafeStaff" then
		
		elseif jobName.Value == "SunsetCleaning" then
			
			local cleaningJob = jobDataFolder:FindFirstChild("CleaningJob")
			local cleaningExperience = cleaningJob:FindFirstChild("CleaningJob_JobExperience")
			local cleaningJobLevel = cleaningJob:FindFirstChild("CleaningJob_JobLevel")

			jobLevel.Text = "Current Job Level: " .. cleaningJobLevel.Value
			jobExperience.Text = "TEST" --"Current Job Experience: " .. "0" --cleaningExperience.Value
			requestedJob = jobName
			
		elseif jobName.Value == "SunsetLifeguard" then
			
		else
			messageText.Visible = true
			wait(4)
			messageText.Visible = false
			print("ERROR - Line 144 " .. jobName)
		end
		
	end
end

I’m not sure why is this happening. The server also still is seeming to have the same problem as before, that a script isn’t setting the var correct. Which is causing the server script to fail.

I listened to your feedback, and I changed all the jobNames so they are universally the same across all the game scripts. I’m confused on what you mean by “job”. If you mean the variable jobName, that is set default to “NoJob” (Or at least when the player is not working at a job.)

Let’s go through the code you have one more time. You execute the function joinJob_UpdateStats, and it gets 2 input arguments. The first is the player, which presumably has a player reference. And the second is the jobName, which you say is set to the default ‘NoJob’.

It prints ‘line 97…’. That means the function at least executes. You pick up the references to the jobDataFolder, and what appears to be a StringValue object containing a string with the players current working-job.

You check if that string with the current job is empty or just a space. Apparently it is, because later on we will see that code inside that if-statement is executed.

So then (after setting the jobText.Text) we get the switch statement, consisting of a long list of if - elseif - else. This is the part I suggested to rewrite with the idiom I proposed (using a table). However, it should do the same, it’s just a rewrite to make it more readable code. Let’s see what it does:

It uses the jobName variable. You mentioned this contains ‘NoJob’, but at this point it is not clear what form it has. From your earlier code, it appeared to be a string, which you could print using print(jobName) (in your earlier code, you called it requestedJob, which seemed a more clear name).

However, your code in this switch acts as if it is a StringValue object. It tries to look for jobName.Value, and if jobName is actually a string (instead of a stringValue object), then the result will be nil. Naturally, all the if-statements will evaluate false, since nil is not equal to any of the strings you compare it to. It therefore naturally ends up in the last else section, and prints ‘ERROR …’

On the other hand, if your jobName is actually a StringValue, and the string in there is ‘NoJob’, then it compares that string ‘NoJob’ to the strings ‘CafeStaff’, ‘SunsetCleaning’, etc until it finds a match. Since none of these strings matches the string ‘NoJob’, it still ends up in the else section, and prints ‘ERROR …’

So I’m not sure what you mean that the code does not do what you expect it to. It seems to either way do exactly what you coded. But I can imagine that you may have gotten confused about wether the input argument jobName contains a string or a stringValue, that is easy to mix up.

Hope this may help any! Good luck!

My code is doing what I intended/wanted it to do. The variable from the client side has the right variable value, but when the remoteFunction comes into play the variable is “appearing” as a blank when it passes from the client → server.

Is that what your seeing as well? Or would you recommend that I do through, and completely wipe the current code. Then go ahead and re-write the entire joining/jobSystem that is currently in place?

Thanks, sorry if I’m just seeing it wrong/not understanding correctly.

I don’t think the value is lost in the remoteFunction. I think it contains ‘NoJob’ and then your server code returns ‘false’.

I would just debug it. I think it’s better to send a string than a stringValue, so I would change

if jobName.Value == "CafeStaff" then

to

if jobName == "CafeStaff" then

And I would add a line:

if jobName == "NoJob" then

To see if that does show up. If that doesn’t answer your question, I would manually send a known value (after you made removed the .Value):

local jobRequest = request_JoinJob:InvokeServer("CafeJob")

As you see in your original example, it printed ‘LINE 37 - NoJob’, and so that means the value was ‘NoJob’, it wasn’t lost. It’s good to use print statements to debug like this, and to do more such ‘sanity checks’ to see if a variable contains what you expect it to contain, when things don’t work as expected.

Careful reading and checking is a big part of scripting. Luau may also help not to mix up your data-types as you send then between function (I still think maybe you mixed up strings and stringValue objects during your tests, leading to this confusion). The code seems close to working, but if you really can’t figure it out, you could start from scratch and copy your code back in bit by bit, checking if everything does what you expect - in particular starting by sending a known value over remoteFunction. Good luck, I think you can figure this out without all that!

I listened to all of your feedback! It all works, thank you so much for being a massive help! :slight_smile:

1 Like