Why is this nil on the client but not on the server?

I’m currently playing around with sleitnick right now, and learning it, and I’m playing with the services currently, and I’ve came across a disturbance.

image

It prints the money fine on the server, and it returns the money amount after calling the method

But when I go to print it out on the client it returns nil, I have been confused about this for quite a while now, and I honestly have no clue on how to get around it.

Output from console:
image

Knit uses promises by default, so I believe that you will need to add a :andThen after the GetClicks

local Clicks = Click:GetClicks(Players.LocalPlayer):andThen(function(result)
    print(result)
end)

I thought you would’ve been correct then, but sadly not

I guess functions you add into the service, which the controller returns, don’t return promises maybe?
I know I have promises enabled, because I use them while initialising the knit process and starting them

Use breakpoints and make sure that the value being turned isn’t nil - or maybe print it before returning just to rule out any issues there.

I am printing it on the server, before returning it, and it isn’t nil, but upon me printing it on the client it is nil

Would it be possible to see the code of your ClickController? It seems like you might be calling :GetClicks() from the controller by mistake instead of from ClickService in the lower half of your second picture.

As far as I know, the following code works:

CLIENT

local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit)

local Players = game:GetService("Players")
local LOCAL_PLAYER = Players.LocalPlayer

local ClickService

local ClickController = Knit.CreateController({
	Name = "ClickController"
})

function ClickController:GetClicks()
	local money = ClickService:GetClicks(LOCAL_PLAYER):expect() -- use andThen/catch for proper error handling
	return money
end

function ClickController:KnitInit()
	-- etc
end

function ClickController:KnitStart()
	ClickService = Knit.GetService("ClickService")
	print(self:GetClicks()) -- will print on both client and server
end

return ClickController

(you could also just do this without any need for a proxy method)

Knit.GetService("ClickService"):GetClicks(game:GetService("Players").LocalPlayer):expect()

SERVER

local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit)

local ClickService = Knit.CreateService({
	Name = "ClickService",
	Client = {},
	StarterClicks = 10,
	PlayerClicks = {}
})

function ClickService.Client:GetClicks(player)
	local money = self.Server:GetClicks(player)
	print(money, player)
	return money
end

function ClickService:GetClicks(player)
	local money = self.PlayerClicks[player] or self.StarterClicks
	return money
end

function ClickService:KnitInit()
	-- .playeradded/removing connections, etc
end

function ClickService:KnitStart()
	-- etc
end

return ClickService

Alternatively, you could use Knit Properties with :SetFor() & :Observe() to handle it instead of constantly needing to do promises.

1 Like

Thank you for this, I pretty much read through your code and compared it to mine, then realised I did one of the most silliest mistakes lol, forgot to return the data in the controller, lol, thankyou for this though :slight_smile:

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