API listColumns visibleOnly param not taking effect?

Coda API (v1) Reference Documentation operation documents the visibleOnly query param, which:

If true, returns only visible columns for the table.

However, specifying this as false does not have any effect, as the operation still only returns the visible columns anyway. Am I missing something?

Sorry, this is a bit confusing. The visibleOnly parameter only applies if you’re requesting information for a base table. A base table is the source of truth for your data, but (perhaps confusingly) the UI lets you hide columns on your base table. So this parameter is what allows you to differentiate between whether you want all of the data your base table contains, or just what you see unhidden in the UI.

When you’re using this endpoint with a view of a table, the parameter doesn’t apply, because a view is in fact defined by the visible rows and columns it contains. This became more confusing a little while back when we released v1 of the API and combined views and tables into a single endpoint–previously there was a separate but largely redundant endpoint for base tables, and this parameter was only available there.

We’ll update the documentation to make this clearer.

Thanks for your response. That’s good to know, and clears things up.

I wanted to touch on your claim that “a view is in fact defined by the visible rows and columns it contains.” IMO this is an assumption about the semantic usage of table features that doesn’t necessarily hold true in all or even most cases. I would tend to agree that a view’s visible rows and columns that differ from those visible in its base table do define the view, as those signify deliberate design choices. However, rows and columns that are visible in neither do not define the view. These could just be under-the-hood bookeeping or formula utilities that are not relevant to present to the doc users in neither the base table nor the view it happens to have. Since it is not possible to discern the intent for why certain rows and columns are hidden on the view, I find the design decision to treat them as defining the view not accurate.

Unless there is another reason I am missing or some associated implementation difficulty, I don’t really understand why the API would omit this functionality, especially since it is already provided and guarded by a param. As a user of the API it would also be possible to conditionally set the flag based on whether the table is a base table or view, so the existing implementation could be preserved (although this change would indeed be breaking :/)

What you describe certainly makes sense, I think it’s mostly a philosophical question. When you create a view in the UI, you’re creating a set of columns, row filters, conditional formats, etc. That set of configuration settings defines the view. It’s kind of philosophical as to whether columns and rows not visible as a result of the configuration are part of the view, or whether those rows and columns only exist in the base table. Coda leans towards emphasizing that those non-visible things actually only exist in the base table. The UI confuses this to some extent because the base table itself has a view–you could imagine though the base table being off of the canvas and having no filters and all columns visible, to emphasize that it is the source of truth of the data, and thus that everything present on a canvas is merely a view of that base table. The fact that the visibleOnly parameter applies only to base table is in this spirit, but we can certainly see how this is confusing.

I definitely get the point you’re making.

I guess my question then is this: given that the API already defines and enables the ability to query for only the visible or the visible + hidden rows/columns of a table, is there any benefit to imposing this philosophy you’ve mentioned (that in a view, hidden rows/columns are actually not part of that view) onto the API when a) this is contradictory to the doc UX (I can click to hide/show columns) and b) it serves only to restrict the functionality of the API without reducing ambiguity (since this is a configuration which would clearly toggle between both use cases independently). It seems to me like even taking this philosophy into account, this param still makes sense as a way to choose only the rows/columns “part of” the view, or the rows/columns part of the view and any of its parent tables.

I’ll cover my use case just to avoid any XY problem: given an arbitrary table (base or view), I want to retrieve all columns for that table (visible or not), as the user would understand it. To my understanding, if the table is a view, this requires an arbitrary amount of recursive calls to traverse the linked parentTable each time until reaching the base, where the call to retrieve the columns can be made.

For your use case, it should only require one call to get the parentTable. That shouldn’t be recursive, the parent of a view is a table, there isn’t a hierarchy of views parented to other views.

The use case can be framed based on the philosophy above, the feature I think is saying “what is the set of all columns of this view’s parent table”, so it takes one call to determine the parent table, then one call to get all its columns.

I can see the confusion about what it seems like the UI is saying conceptually when you unhide columns in the column list for a view. It could very reasonably be perceived as “I’m toggling the visibility of columns present in this view” but what it’s actually doing is changing the definition of the view. That is, hiding a column in the UI removes the column from the view. This distinction is much more apparent in the API, which more closely resembles the underlying conceptual model, than in the UI.

While I think we probably could technically make visibleOnly=false work for views with some hackery, it’s likely to get us into implementation trouble to try to expose concepts that only apply in the data model to base tables, to views in the API. We’re more likely to go the other direction and draw a stronger distinction between base tables, which are unfiltered data, and views, which are inherently filtered.

1 Like

With the understanding that “it should only require one call to get the parentTable” the usability difference from the perspective of consuming the API is negligible. So i’ll agree with you that an implementation change is not appropriate here.

The use case can be framed based on the philosophy above, the feature I think is saying “what is the set of all columns of this view’s parent table”, so it takes one call to determine the parent table, then one call to get all its columns.

This makes a lot of sense