Populate "Select" list from query

Good morning all,

I am taking my first crack at app building, so far it hasnt made me want to run away, but I am having trouble with populating "Select Box" using query values. Let me open with I have tested 2 queries and both produce exactly what I expect.

Ron West made a comment last year that looks like a strong possibility to be my culprit:
" You can connect data sets directly to the selection component by switching the 'Options' property from Manual to Mapped. And then placing in code like this:{{ MonetAlwaysDataDB.data }}" The full thread is titled Populate Dropdown Text & Value From Query to Custom Component

I am not seeing the OPTIONS property to make this switch from Manual to Mapped. The option that I am working on is a "SELECT" box, listed with the Forms group within the Create Components.

Any assistance is appreciated.

Welcome!

When you select the Select component in your app workspace, the inspector should show you something like this:

image

Switch to mapped mode and you should see the options look like this:

image

When you look at the Data Source dropdown here, you should see options to use JavaScript, an array or other query used in the app:

image

If you can get to here you should be able to follow along with the rest of the instructions in the post you linked.

Good morning and thank you for the fast reply,

I checked the Select box that I have been working with and then tried adding a new one, I did not see the manual/mapped option on either.

It is very possible that I am overlooking something and not working with the correct property inspector, I just started playing with this tool this week and can already see I have a lot to learn.

In this case you can just directly attached the data in "Values" and "Labels".
Here I fetch the names column from the table and they show up in the dropdown.

1 Like

That got it to run as expected, thank you.

A question for what is coming next:
This is the first in a series of 4 select boxes, I am after vehicle make, model, year, and engine size. Goal is to have a list of 350 models filtered down to those models that match the make value selected in the first box.

How do I refresh the query for the second select box to filter it based on the selection of the first?

The second select box's values/labels should be set to something like {{yourQuery.data.filter(x => x.name === firstSelectBox.value).make/model/etc...}}

Can you explain the x => x.name part of this, I think I was able to put the rest of it together. I am guessing this is looking into the query field for the record values that match the selected value; I am not sure what the syntax will look like.

The query that feeds the list is named ModelSelect
The field name to match values with select box to the select box is: Veh_Make_ID
The name of the select box value to match is SelectMakeCB

I am guessing that the right side of the x statement above will look like: => ModelSelect.Veh_Make_ID

It is the left x that I am not sure what value should be expressed. If there is a name for this process that I can research and study, please let me know as this process is one that I will use a lot in this project.

You've got the right idea.

Using the filter method of an array requires you to define a function for what you are filtering against in the array. You can look up how to define a function outside of the filter(...) code but what I am showing is called an anonymous function. The syntax (x => x.name === firstSelectBox.value) is saying for every member of the array (which for the purposes of definition we call 'x') compare the .name property of each member of the array against the current firstSelectBox.value. Since 'x' can be defined to be anything your final query would be:

{{ModelSelect.data.filter(x => x.Veh_Make_ID === SelectMakeCB.value)}}

To repeat: you don't need to use "x" -- you can use any variable name to describe an element in the array here. {{ModelSelect.data.filter(y => y.Veh_Make_ID === SelectMakeCB.value)}} or {{ModelSelect.data.filter(myVar => myVar.Veh_Make_ID === SelectMakeCB.value)}} or {{ModelSelect.data.filter(item => item.Veh_Make_ID === SelectMakeCB.value)}} all do exactly the same thing.

Good morning again,

I have been playing with the filter, but no luck yet. One thing that is curious to me is that when writing {{ ModelSelect.data.filter; as soon as the word "filter" is added, the box turns red and I am prompted with
TypeError: ModelSelect.data.filter is not a function

Here is what I have in the values box:
{{ ModelSelect.data.filter(model => model.Veh_Make_ID === SelectMakeCB.value). Veh_Model_Text }}

If I take the filter portion out, the box will populate with an unfiltered list, I am pretty sure my problem is in the filter syntax.

Depending on the type of query ModelSelect is running you may need to adjust the code slightly to ensure that the data is properly formatted as an array before filtering:

{{formatDataAsArray(ModelSelect.data).filter(model => model.Veh_Make_ID === SelectMakeCB.value).Veh_Model_Text}}

might get you there

Still not there, here is the error message:
ReferenceError: filterDataAsArray is not defined

One thing I have noticed is that the word filter will cause the box to turn red and produce the messages like above. Are there any other commands that may do the same thing?

Ah, that would be because the method is actually called formatDataAsArray -- my mistake!

I just updated the original reply with the change.

Getting closer, that turned the box green, but still not getting a list; any thoughts? One thing that I did try to attempt troubleshooting: I created another Select box and tried filling with an unfiltered list of models. Command I used for values: {{formatDataAsArray(ModelSelect.data).veh_model_id}}
I do know that the query is working as expected and I have tried to call works using: ModelSelect.data.veh_mod_id
I am wondering if I am not using the formatDataAsArray correctly.

I went back and checked inputs thinking I may have missed called a name; all appears good on that part.

I am trying to better understand our filter command, is there any place I can study this topic or is it crash around and memorize what works?

Can you provide a few screenshots of the ModelSelect query and its return data?

You can review most JavaScript methods with some Google-fu. Here's a Mozilla Developer page about the filter method:

If the data from your query is already an array, you should be able to just use it as-is (without the formatDataAsArray). It seems like this is processing the values into an array, but with no values either the query returned no data or the data wasn't formatted properly to be parsed by the formatDataAsArray method to have the additional property you were looking to display (no Veh_Model_Text property).

Okay, so I think you needed to have setup the select portion slightly different:

{{formatDataAsArray(ModelSelect.data).filter(model => model.veh_model_id === SelectMakeCB.value)}} (without the additional .Veh_Model_Text on the end will be your filtered list of data. On the component itself, you want to show the values of a separate property:

image

In your mapped options, you would place {{item.Veh_Model_Text}} in the Value and Label properties.

JUST REALIZED THAT YOU ARE USING THE MOBILE COMPONENT... and the above is for desktop apps.

You will need to use a separate transformer to parse out the values, then. and the transformer becomes the default data source for your component

I am not sure what you mean when you say "transformer", can you tell me a little more about this?

My goof on not mentioning that this was a mobile app that I was working with, glad you caught it.

A transformer is like a JavaScript query except that you don't need to trigger it. It takes inputs from other queries, components or variables that is updated when any of the inputs are modified.

You can add a new transformer just like any other query and then fill in the code to return just the data you need for this component on Mobile (I think):

transformer2

const data = {{formatDataAsArray(ModelSelect.data).filter(model => model.veh_model_id === SelectMakeCB.value)}}

return formatDataAsObject(data).Veh_Model_Text

The new component's data source would be set to the transformer values:
image

This way, whenever users change the SelectMakeCB input the transformer updates and only supplies the model values back from the initial dataset. If you had multiple stages of selections you could setup a few different transformers to run based on changes to the previous selection in the process.