Search code examples
nullgodotgdscript

Why is my function returning null/nil?? - Godot


So, I'm trying to make a function that returns a Dictionary and for some reason it is returning Nil every time I use it. Even though all the endings are returning something! I've restarted the editor and tried some debugging, but couldn't get it to work. Here is my script and error:

Script:

func getItem(itemName:String) -> Dictionary:
    if is_name_in_inventory(itemName):
        if inventory.item1.name == itemName:
            return inventory.item1.merge({"index": 1, "error": false})
        elif inventory.item2.name == itemName:
            return inventory.item2.merge({"index": 2, "error": false})
        elif inventory.item3.name == itemName:
            return inventory.item3.merge({"index": 3, "error": false})
        elif inventory.item4.name == itemName:
            return inventory.item4.merge({"index": 4, "error": false})

        print("Unknown error finding an inventory item...")
        return {"error": true, "errormessage": ""}
    
    print("That name does not exist!")
    return {"error": true, "errormessage": "That name does not exist!"}

Error:

Invalid call. Nonexistent function 'get' in base 'Nil'

I am using the function like this: getItem("item").get("error", false)

I tried to use a function to get a Dictionary and was expecting something not nil


Solution

  • The issue is that merge is void. I quote from the official documentation on merge:

    void merge ( Dictionary dictionary, bool overwrite=false )

    Adds elements from dictionary to this Dictionary. By default, duplicate keys will not be copied over, unless overwrite is true.

    Thus, the lines that look like this:

    return inventory.item1.merge({"index": 1, "error": false})
    

    Would:

    1. modify the dictionary that you have in inventory.
    2. return null.

    And you don't want that.


    You might be wondering why Godot is not complaining about this. As it turns out, it is a quirk of Godot 3 that Array and Dictionary are nullable, sometimes.


    Anyway, you can work around it by declaring the dictionary you want to return. For example:

    var result := {"index": 1, "error": false}
    result.merge(inventory.item1)
    return result
    

    In other notes, perhaps you would benefit from making item1, item2 and so on into an Array so you can iterate over them instead of making an if for each one.