The Fault in our Select Default

One thing I haven’t quite figured out in Angular 2 yet relates to the ‘select’ element on forms.  Creating one by *ngFor – ing through a dataset makes sense, but every time the ‘selected’ option fails to set, leaving me with a drop down that appears empty until clicked.

What I wanted was a generic default option- like you’d normally do by setting the ‘selected’ property on the element.  Something like ‘Select Item Below’- so people know there’s the option, but the first element in the actual select array isn’t shown yet.  But it just didn’t seem to want to work.  Even if I manually added an option element above the *ngFor loop through the other option elements (provided by a call to the Angular controller), and set the ‘selected’ attribute on that first element, it just appeared in the list- it was not selected by default.

I’m betting there’s an easy way to do this, but I didn’t find it.  Instead, this is what I did in a ‘setDropdownOptions’ method on my component:

this.optionsUser = this.audit
    .map(entry => entry['user_key'])
    .filter((name, index, arr) => {
        return index === arr.indexOf(name);
    });
this.optionsUser.unshift('Choose User Email');

this.optionsUser is just an empty array to begin with.  The first part loops over the audit array to get the user_key (an email address), then return just that into the optionsUser array (the extra .filter call weeds out any duplicates).  Then, we unshift (add to the front of the array) the generic text for the default menu item.

One more step in the component- the select element is part of a FormControl Angular element.  We set this specific control to a variable called ‘this.termUser’ when initializing the form.  That way, once the array of ‘optionsUser’ is populated, and we unshift the generic title on the front, we can set the initial value:

this.termUser.setValue('');

Finally, in the template, we just loop over the optionsUser array as normal to display the available options from the database, but on each iteration, check to see if the option === our default text (‘Choose User Email’ in this case).  If so, set the value for this select element to an empty string (making it the default selected, but also meaning that if it’s submitted, it won’t alter our returned array at all):

<select class="form-control" formControlName="user_key">
    <option *ngFor="let item of optionsUser" value="{{item === 'Choose User Email' ? '' : item}}">
    {{item}}
    </option>
</select>

Does it work?  Yes.  Is it pretty?  Maybe.  Is there a better way?  Probably.  We’re working on abstracting it a bit more to make it a reusable option (instead of hard coding the default text, pass it as variable)- more on that later!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s