How ng-style Helped Me

Recently I was working on trying to dynamically strikethrough values in a list in an Angular Project. This is pretty straightforward and works with the standard css text-decoration: line-through , but that’s harder to do if you want to apply this style dynamically.

Looking around stack-overflow, lots of people have ways to fix this.

I wanted to be able to dynamically stirke-through a line, and save it in a way that my app could automatically apply this when values are loaded.

The app was hosted with Firebase and I wanted to take advantage of the remote state management feature. With Firebase, your data uses observables to listen to streams from the data’s source. I talk about it more in my Angular-In-Depth post here.

Back to my story…

So I wanted to dynamically apply a strike-through. This ended up actually being kinda challenging, becuase I wanted the strike-through to be applied on-load. Kinda like the following:

I wanted to the following in my app:

  1. store the list
  2. store the fact that some values have strike-through.
  3. on load, I wanted to dynamically apply the strike-through
  4. when users click the checkbox, the stirke-through is applied

The first item was super straightforward, Just using the AngularFire2 library I wrote a little method that takes in the values and saves:

  // async is not necessary here, but using it to control event loop
  async addItem() {
    const id = this.afs.createId();
    const groceryItem: GroceryItem = {
      value: this.createForm.controls.item.value,
      lineThrough: false,
      id: id
    };
    const createCall = await this.groceryItemsCollection.doc(id).set(groceryItem)
      .catch(() => new Error('Error when creating item'));

    if ( createCall instanceof Error) {
      return alert(createCall);
    }

    this.createForm.controls.item.setValue('');
  }

If you notice, in the values stored I included a lineThrough boolean value. This is where I’m storing the strike-through value. This takes care of #2 above as well.

However, how do pick this up? Add a listener for the click event to the checkbox, then when it is saved, apply the associated value

Listen for the value in the template html:

<mat-checkbox (click)="linethrough(groceryItem)" [checked]="groceryItem.lineThrough"></mat-checkbox>

Listen for the change and update the local value:

  async linethrough(groceryItem: GroceryItem) {
    if (groceryItem.lineThrough) {
      groceryItem.lineThrough = false;
    } else {
      groceryItem.lineThrough = true;
    }
    const updateCall = await this.groceryItemsCollection.doc(groceryItem.id).set(groceryItem)
      .catch(() => new Error('Error when creating item'));

    if ( updateCall instanceof Error) {
      return alert(updateCall);
    }
  }

Dynamically read in the value from firebase onload:

WOAH! WOAH! What is [ngstyle] doing there?

This was my magic solution.

If you google [ngstyle] you’ll find a lot of articles on how it dynamically allows you to apply styling.

In this case, what I’m doing is I’m applying the text-decoration: line-through based on the values that are brought in.

What does this enable me to do?

EVERYTHING! J/k but it is pretty cool. This all basically let me setup this dynamic value, based on a checkbox and accomplished my goals.

I recommend checking out some more on [ngstyle] when you have some time. Its pretty cool and gives you a lot of flexibility in your templates.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s