JSON table value is nil

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I’m trying to give player’s clothing when they join and that clothing to save when they leave the game and load the same clothing when thet join back.

  1. What is the issue? Include screenshots / videos if possible!

So I created a diccionary to store the player’s Shirt and Pants templates. The thing is that when a player with saved data tries to rejoin the game it will give this error on the function that gives player’s clothing:

“ServerScriptService.ClothingSystem:40: attempt to index nil with ‘ShirtTemplate’”

I thought it would be that probably I didn’t saved the value correctly and it was a nil, however when I tried printing it, it actually printed the player’s clothing so that wasn’t the problem.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

As it’s usual for me, I’m the only one who got this problem (or at least I think so.) because I just learnt what is Json and how to “use it” yesterday.

This is the full code:

local Module = require(game.ReplicatedStorage.Modules.Functions)

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("PlayerClothingDatastore")
local HttpService = game:GetService("HttpService")

function addClothing(player, character, ShirtId, PantsId)
	repeat wait() until player:HasAppearanceLoaded() 
	local Shirt
	local Pants
	if not character:FindFirstChildOfClass("Shirt") then
		Shirt = Instance.new("Shirt")
		Shirt.Parent = character
	elseif character:FindFirstChildOfClass("Shirt") then
		Shirt = character:FindFirstChildOfClass("Shirt")
	end
	if not character:FindFirstChildOfClass("Pants") then
		Pants = Instance.new("Pants")
		Pants.Parent = character
	elseif character:FindFirstChildOfClass("Pants") then
		Pants = character:FindFirstChildOfClass("Pants")
	end

	local success, model = pcall(function() 
		return game:GetService("InsertService"):LoadAsset(ShirtId) 
	end)
	
	if success then 
		model.Parent = workspace.Clothing
	end

	local success2, model2 = pcall(function() 
		return game:GetService("InsertService"):LoadAsset(PantsId) 
	end)
	if success2 then 
		model2.Parent = workspace.Clothing
	end

	wait()
	if Shirt then Shirt.ShirtTemplate = model.Shirt.ShirtTemplate end
	if Pants then Pants.PantsTemplate = model2.Pants.PantsTemplate end
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(Character)
		local success, data = pcall(function()
			return DataStore:GetAsync(player.UserId)
		end)
		
		if success and Character:FindFirstChild("Pants") and Character:FindFirstChild("Shirt") then
			print("Successfully obtained data for player",player)
			if data then
				print("Data was found!")
				local Decoded_Json = HttpService:JSONDecode(data)
				local ShirtID = tostring(string.sub(Decoded_Json["Shirt"], string.find(Decoded_Json["Shirt"],"=")+1, string.len(Decoded_Json["Shirt"])))
				local PantsID = tostring(string.sub(Decoded_Json["Pants"], string.find(Decoded_Json["Pants"],"=")+1, string.len(Decoded_Json["Pants"])))
				addClothing(player, Character, ShirtID, PantsID)		
			else
				wait()
				print("Data wasn't found")
				addClothing(player, Character, Module.GetShirt(), Module.GetPants())
				wait()
				print("New Data Saved")
				local Table = {
					["Pants"] = player.Character:WaitForChild("Pants").PantsTemplate,
					["Shirt"] = player.Character:WaitForChild("Pants").PantsTemplate
				}

				local NewData = HttpService:JSONEncode(Table)

				local success, err = pcall(function()
					DataStore:SetAsync(player.UserId, NewData)
				end)

				if success then
					print("Data saved for player",player)
				else
					print("Data did not save for player",player,err)
				end
				
			end
		else
			print("Couldn't load data for player",player)
			player:Kick("Rejoin please")
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local Table = {
		["Pants"] = player.Character:WaitForChild("Pants").PantsTemplate,
		["Shirt"] = player.Character:WaitForChild("Pants").PantsTemplate
	}

	local data = HttpService:JSONEncode(Table)

	local success, err = pcall(function()
		DataStore:SetAsync(player.UserId, data)
	end)

	if success then
		print("Data saved for player", player)
	else
		print("Data couldn't save for player", player, err)
	end
end)

game:BindToClose(function()
	for i, player in pairs(game.Players:GetPlayers()) do
		local Table = {
			["Pants"] = player.Character:WaitForChild("Pants").PantsTemplate,
			["Shirt"] = player.Character:WaitForChild("Pants").PantsTemplate
		}
		
		local data = HttpService:JSONEncode(Table)
		
		local success, err = pcall(function()

			DataStore:SetAsync(player.UserId, data)
		end)

		if success then
			print("Data saved for player",player)
		else
			print("Data couldn't save for player",player,err)
		end
	end
end)

Hope you can help me, I’m really having struggles understand Json and HttpService in general. :heart:

1 Like

Are you able to print the value on line 55 of ShirtID? It appears that the error is because one of the 2 objects on line 40 are literally nil

The nil value is the model with the clothing that was supposed to load with InsertService however it doesn’t. I confirmed at the time of calling the function that both ShirtId and PantsId weren’t nil, they weren’t. So yeah, I can print ShirtID on line 55

added to this I printed ShirdID, PantsID, ShirdId and PantsId just to be sure.

>  18:49:21.988 - 1971990318  -  Server - ClothingSystem:59 (Print I did to check ShirtID)
>   18:49:21.988 - 2108337429  -  Server - ClothingSystem:60 (Print for PantsID)
>   18:49:22.440 - 1971990318  -  Server - ClothingSystem:39 (Print in the function for ShirtId)
>   18:49:22.440 - 2108337429  -  Server - ClothingSystem:40 (Print for PantsId)

I just input the item ID, it looks like you’re using LoadAsset for a Decal? The code makes it look like a model though, so I believe that’s where the issue stems. I believe you’d have to upload a shirt and then just use the shirt id instead of loading the asset

So, thank you for the help. You were right but that wasn’t exactly the problem. You made me check the whole scripted that allowed me to find some other small errors but the main problem was the fact that apparently InsertService is broken (InsertService:LoadAsset(id) is not loading in Models - #7 by Vorlias)

1 Like

So, I tried using humanoiddescription instead. and in this case, it prints an error :

Humanoid::ApplyDescription() Failed to load Pants, default applied
Humanoid::ApplyDescription() Failed to load Shirt, default applied

it was dumb of me to say that it was insert service if it worked, and gave clothing to the player if he didn’t have any data. again I printed both ID’s and none of them is nil