Table isn't empty but function says so

So the function returnPlayerData, the print statement there prints a blank table.
Even though when a player is added GlobalData[player.Name] = {} is added to the GlobalData table. It even prints all the print statements when the player joins. I don’t know why this is happening.

Script:

local InventoryDS = game:GetService("DataStoreService"):GetDataStore("InventoryDS_V1")

local Inventory = {}
local GlobalData = {} -- Global Data, Holds all player's data

function Inventory:init()
	game.Players.PlayerAdded:Connect(function(player)
		print(1)
		local inventoryData

		local _, err = pcall(function()
			inventoryData = InventoryDS:GetAsync(player.UserId)
		end)

		print(2)

		GlobalData[player.Name] = {}

		print(GlobalData)

		if err then
			warn(err)
		elseif inventoryData then
			print(inventoryData,GlobalData)
            for name, data in pairs(inventoryData) do
				print(name,data)
                GlobalData[player.Name][name] = data
            end
			print(GlobalData)
		end
	end)

	game.Players.PlayerRemoving:Connect(function(player)
		local success, err = pcall(function()
			InventoryDS:SetAsync(player.UserId,GlobalData[player.Name])
		end)

		if success then
			GlobalData[player.Name] = nil
		else
			warn(err)
		end
	end)
end

function Inventory:returnPlayerData(player)
	print(GlobalData)
    return GlobalData[player.Name]
end

return Inventory

Calling script

local CratesModule = {}

local CratesInfo = require(script.Parent.CratesInfo)
local TableUtils = require(game.ReplicatedStorage.TableUtils)
local Inventory = require(game.ServerScriptService.Inventory)

function CratesModule:open(crateName)
    local Crate = CratesInfo[crateName]
    local BundleChosen,BundleName = TableUtils.DictionarySelectRandom(Crate)
    local playerData = Inventory:returnPlayerData(self)

    print(playerData)
    print(BundleChosen,BundleName)

    playerData[BundleName] = BundleChosen
end

return CratesModule
 

In your CratesModule:open function what is the value of self if you print it before you call returnPlayerData?

It prints the player.

Btw to test this, this is what I run.

require(game.ReplicatedStorage.Crates.CratesModule).open(game.Players.MrGameboy123456789,“VictoryCrate”)

I’m not sure how your PlayerAdded function would actually get called as by the time init would be called the player would have already joined the game so it wouldn’t be able to initialize them. Something you could do is move the PlayerAdded and PlayerRemoving out into their own Script and they simply call two new functions in your inventory module called loadPlayerData and clearPlayerData respectively and the code would be just what you had inside those functions in that module already like so:

function Inventory.loadPlayerData(player)
    print(1)
    local inventoryData

    local _, err = pcall(function()
        inventoryData = InventoryDS:GetAsync(player.UserId)
    end)

    print(2)

    GlobalData[player.Name] = {}

    print(GlobalData)

    if err then
        warn(err)
    elseif inventoryData then
        print(inventoryData,GlobalData)
        for name, data in pairs(inventoryData) do
            print(name,data)
            GlobalData[player.Name][name] = data
        end
        print(GlobalData)
    end
end

function Inventory.clearPlayerData(player)
    local success, err = pcall(function()
        InventoryDS:SetAsync(player.UserId,GlobalData[player.Name])
    end)

    if success then
        GlobalData[player.Name] = nil
    else
        warn(err)
    end
end

function Inventory.returnPlayerData(player)
    print(GlobalData)
    return GlobalData[player.Name]
end

New Script would have these:

game.Players.PlayerAdded:Connect(function(player)
	Inventory.loadPlayerData(player)
end)

game.Players.PlayerRemoving:Connect(function(player)
	Inventory.unloadPlayerData(player)
end)

Something Like this should work:

function CratesModule:open(crateName)
    local Crate = CratesInfo[crateName]
    local BundleChosen,BundleName = TableUtils.DictionarySelectRandom(Crate)
    local player = game.Players:GetPlayerFromCharacter(self.Parent) 
    if not player then return end 
    local playerData = Inventory:returnPlayerData(player)

    print(playerData)
    print(BundleChosen,BundleName)

    playerData[BundleName] = BundleChosen
end

Can’t test it rn though