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.

Engineer, husband, learner, and Star Wars fan. View all posts by Andrew Evans

Originally published at https://rhythmandbinary.com on June 27, 2019.

Husband, Engineer, OSS Contributor, and Manager at CapTech Consulting. Follow me on https://rhythmandbinary.com and https://andrewevans.dev

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store