Angular self-saving dropdowns — yet another directive

Bharath Ravi
4 min readJul 24, 2021

--

“It is not enough for code to work” — Robert C. Martin

This story was originally published at inDepthDev

The angular directive is a powerful pattern provided by the framework which can be used to add additional behaviors to the elements. We will create a custom Angular directive in this article to enable self-saving (autosaving) for dropdown elements.

What is a self-saving dropdown anyways?

Consider this simple scenario in an example application where you have a dropdown to determine the sexual age group of a person. The natural and efficient implementation of this case is to use a dropdown with options. It is typical to use a form with a dropdown field and a submit button. But what if this dropdown is not part of a larger HTML form? What if this is a single select item on the page without a save button? You might not want the user to click a button to initiate the save in some cases as it can cause friction.

We can use a self-saving dropdown that syncs the state with the backend database on dropdown change events. You can find this pattern commonly in react applications with the data fetcher approach where the component is responsible for fetching its required data itself.

Great! Now, how do we communicate to the user that this change triggered a save? How do we let users know in case of an error?

It is obvious that we need an elegant solution to provide visual feedback to the user of in-progress, success, and failure events. This is where you might want to implement self-saving behavior.

Let’s get to it

Take a peek into the final results on how it works before we start.

That looks cool, doesn’t it?

Let’s now outline the plan

  1. The directive should take an input that refers to the HTTP call being made to the backend.
  2. When the host element triggers the ‘change` event, we need the listener to run.
  3. Need to show the loader before the subscription
  4. Need to remove the loader, add green tick icon on a successful call
  5. Need to remove the tick mark after one second
  6. On failure, need to show the error icon next to the select field

In the diagram,

Flow chart — self saving dropdowns

Let’s start by creating an Angular directive using the Angular CLI.

ng generate directive self-save

We will have only one input to this directive, ie

@Input(‘observableFn’)
observableFn!: () => Observable<any>;

`ObservableFn` will have the reference to the HTTP request that has to be made to save this particular data. We will be passing this information down from the parent where this directive is getting used.

Let’s now bring in ElementRef, Renderer2, and Document

constructor(
private elRef: ElementRef,
private renderer: Renderer2,
@Inject(DOCUMENT) private document: Document
) {}

We will be using these dependencies to

  1. ElementRef — Refer to the host element
  2. Renderer2 — To Attach the error text element in case of error
  3. Document- reference to the document

We need to listen to the change event on the host element to know when the dropdown value changes

@HostListener(‘change’)
onChange() {
// Do all craziness
}

Let’s start implementing the self-saving behavior now,

We are making use of the elementRef to grab the native host element(select element) as we need to manipulate this as we go. Next, we are subscribing to the observable that is already passed as the input by calling the input function. There are two helper methods here to which we are passing the select element. Let us now see how they are implemented.

This code follows the initial flowchart that we created. ie, on change of the dropdown value,

  1. Adds a loader to the element to indicate save in-progress
  2. Gets the HTTP observable and subscribes

On success

  1. Removes the loader background
  2. Add success tick icon
  3. Remove the tick icon after 1 second

And on failure,

  1. Create a dummy div element to hold the error text
  2. Populated the innerText as the error message received from the server
  3. Use Renderer to append this child element to the parent node so that the error message is not displayed below the dropdown

Let us now implement these helper methods that we used above,

To add a loader to the dropdown

The same can be followed to add the success indicator as well,

Now to implement the addBackground() method,

We can simply set the element background to `none` to remove the background

Now to use this directive on any select element,

Let us also create the post() method which returns a function that returns the HTTP observable.

You can play around with the stackblitz project here.

Conclusion

Directives are very handy when it comes to a repeated pattern that we need to apply to multiple elements in our application. They can be used to make reusable patterns across the application and make the developer’s life easier by keeping the application cleaner!

--

--

Bharath Ravi
Bharath Ravi

Responses (1)