A simple list of anything field returns "properties.list.length is not a funtion"

There’s no bug here. You’re just indiscriminately calling .length(), forgetting that, if there’s no expression provided for your field called list, the value there will be null instead of a List object.

Now, in your screenshot, you’ve got list set up so it’s not optional. All that does is activates the Issue Checker to warn the Bubble programmer that this field should have an expression in it.

However, that does not relieve you (the plugin author) of the responsibility to check that there is actually a value in properties.list before trying to access the get() or length() functions on that List object.

If the user leaves the field empty, the value you get for properties.list will be null, not a List object and when you do properties.list.length() there is of course no function there (null.length() is not a thing).

So, typically what we do when we are resolving our properties — particularly if we are need to use these values in other places all around your plugin code — is move them from the properties object to some other variable OR (and this is way better) put them on the instance object using instance.data.

So for your field you named list:

var the_list
the_list = properties.list ? properties.list.get(0, properties.list.length()) : []

:point_up: that is, if properties.list is non-null, get the list, otherwise return an empty array.

Bonus beats:

If you’re gonna be doing a lot of stuff with lists, it’s a good idea to just make a list getting function to make this easier.

Like, you might set one up like:

function getList(List) {
    var returnList = []
    if (!List.hasOwnProperty('get')) return returnList
    if (!List || List.length() < 1) return returnList 
    // this next step would just return us our array of items
    returnList = List.get(0, List.length())
    // however we might want to just get some field or whatever... you could add a "field" argument to this function or do other fancy stuff instead, e.g.,
    // returnList = List.get(0, List.length()).map(item => item.get('_id'))
    return returnList
} // end getList

And further, what I like to do with functions like these is put them in instance.data so we can access them anywhere in our plugin (define them in initialize!):

instance.data.funcGetList = function getList(List) {
        var returnList = []
        if (!List.hasOwnProperty('get')) return returnList
        if (!List || List.length() < 1) return returnList 
        // this next step would just return us our array of items
        returnList = List.get(0, List.length())
        // however we might want to just get some field or whatever... you could add a "field" argument to this function or do other fancy stuff instead, e.g.,
        // returnList = List.get(0, List.length()).map(item => item.get('_id'))
        return returnList
    } // end getList

And then in your update function:

instance.data.the_list = properties.list ? instance.data.funcGetList(properties.list) : []

1 Like