Most information that you will use in your Bubble application will be dynamic, and coming from the database, or from other sources of data, such as external APIs (plugins). In this cases, you will use the Expression Composer to define an expression that will displayed as expression in edit mode and evaluated in run mode. For instance you will see in the Editor 'Current user's email', which may become in run mode, depending on who is logged in, 'email@example.com'.
The Expression Composer is a key element of the Bubble Application Editor that lets you build these expressions without typing anything, but instead by picking some options in some dropdown menus. The system will automatically prompt you in the next menu with options that are available given what you have selected so far. For instance, if the first, main entry in the expression is 'Current User', the next menu will offer options such as 'is logged in', 'is not logged in', 'email', etc.
The composer lets you build complex expressions by combining different sources of data. It is important to note that the evaluation happens from the left to the right, without parentheses priorities.
Expressions' types are evaluated in edit mode to validate the type consistency (as explained above. For instance, if you are trying to display the Current User's email in a text element, 'Current User' won't be valid, as it is not a text, while 'Current user's email' will be valid. When an expression isn't valid, it will be reported as an issue in the Issue Checker and the whole expression will be displayed in red.
The run-mode debugger is very useful to understand how an expression is evaluated. See the relevant section for more information.
Datasources are where you get your data from when designing a dynamic expression. It is going to be the first section of the expression.
Sources of data can be a search from the database, the current user, data from an external API, some page and browser information, etc. This section covers the key data sources. You can find details for all data sources in the Reference.
This data source lets you fetch entries of a given type from the database and returns a list of this things. This can be used in repeating groups to display a list, to check the existence of some entries (by checking the length of the list), etc.
A search is defined by a type of data to look for (for instance 'user', or 'car'), and optionally some constraints and sorts options.
You can define some constraints to narrow the search and only fetch items that meet these constraints. For instance, you may want to find cars whose price is between two values, etc. Defining a constraint works by picking the field you want the constraint to apply to, and then defining a comparison operator (such as =, <, >, contains) and then define the value to be compared with, either a static value or a dynamic expression. A search without constraints will return all the entries in the database of that type
You can either search by field, or do a all-field search. In such a case, the Search Engine will retrieve all entries that contain the text define as the value for the constraint.
When an expression is evaluated to an empty value, the constraint is ignored, by design. For instance, let's say we are performing a search on a page for cars, and you let users type a maximum price in an input. If you are using the value of this input in a search constraint on the price field, and if the user has not typed anything, all cars will be retrieved (instead of returning no cars).
The 'Get Data from API' data source lets you fetch data from an external service or server and returns a list of objects of that type. If you add some plugins to your app that offer some datasources, you will see some options in the dropdown for the API provider.
Each API has different parameters, and the User Interface will prompt you to enter the relevant values. For instance, the Google Places API will need you to enter a value for what you're looking for ('cafe', 'restaurant', etc.) and an address. Here again, as you would do in a search, you can use dynamic expressions to make these API parameters dynamic.
Please refer to the Plugins Chapter for more information regarding plugins.
The current user represents the currently logged in user. This gives you access to the different fields that are defined on the user type, in addition to the few built-in fields as explained above.
In workflows, when an action returns some data, you will often want to access the result of the previous operation in the subsequent actions. For instance, an action may create a thing of type 'order', and you need to get the ID of this thing to send it in an email. The 'Result from Previous action' data source lets you do this.
This is one of the most common datasources. In Bubble, container elements can have a thing attach to them, so that all elements inside can access this thing. You can control which thing a group has in its context by modifying the data source field or by using a Display Data in group action.
A repeating group functions in a similar way. Each cell will have a thing in its context that can be accessed as a datasource.
Bubble has a few operations that can be applied to lists. In particular, you can apply sorting and filtering to a list of things. These are different from search constraints as they are evaluated after the list is retrieved from the database, and therefore can lead to slower performance. You can read more about list option in the reference.
Editing dynamic expressions happens through the subsequent dropdown menus. You can use your mouse to pick the right option, and can also your the keyboard. Pressing the arrow keys lets you navigate the options, while pressing 'delete' will go back up in the expression and delete the subsequent entries.
Bubble also has a few tools that help maniplulating long expressions. You can find them with the contextual menu, but right clicking on an expression. In particular, you will be able to copy / paste expressions, insert some dynamic expressions if you are working on a text expression with some dynamic entries, and reveal the element or the action an expression is referring to (if any).