NativeScript + Angular: Icons as a service

William Luce
2 min readMay 21, 2019

--

I have a hard time imagining a mobile app without icons. Whether used as companions to text or as a complete replacement, icons communicate the intent of a feature to users.

Setting up icon fonts in NativeScript + Angular applications is outlined in the docs, and you end up with something like this.

<Label text=”&#xf019;” class=”far”></Label>

Why change this?

Seems simple enough. It’s a one liner and not all that complicated. Why change it?

  1. I don’t have a clue what icon that is. I want to be able to declare that I want to use the home icon, not &#xf019.
  2. It’s dependent on setting the class to use the icon font. Because it’s the same every time, we can abstract that way.
  3. It feels weird to use a Label with text to get an icon. 🤷‍♂️

Enter the <app-icon> component

Instead, I’d rather abstract that ugliness away into a component with an API something more like…

<app-icon name="home"></app-icon>

It’s a multistep process to get there responsibly. First, an IconService to perform the transformation from the icon name I ask for to the character code string the Label needs.

import { Injectable } from "@angular/core";import { ICON_MAP } from "./icon.map";@Injectable({  providedIn: "root"})export class IconService {  public get(name: string): string {    try {      return String.fromCharCode(ICON_MAP[name]);    } catch(e) {      return '';    }  }}

This service is part of the CoreModule, which is imported to the AppModule and never any other module. Meaning it’s a singleton and only ever instantiated once. This is important because the IconComponent is part of the SharedModule which is imported into every module except the AppModule.

import { Component, OnInit, Input } from "@angular/core";import { IconService } from "~/app/core/icon/icon.service";@Component({  selector: "app-icon",  template: `    <Label [text]="iconString" class="ico"></Label>  `,  styles: [],  moduleId: module.id})export class IconComponent implements OnInit {  @Input() name: string;  public iconString: string;  constructor(private _iconService: IconService) {}  ngOnInit() {    this.iconString = this._iconService.get(this.name);  }}

Thoughts

Things like this seems small. After all, it was just one line and this solution adds infrastructure to the application that will have to be managed/maintained over time.

The result though, is a more intuitive and error resistant API for using icons. Code bases that focus on these small improvements are fun to work in and enhance productivity.

Source

https://github.com/WillLuce/nativescript-angular-icon-fonts

--

--