DEV Community

Cover image for The Fastest Way To Build Lightweight Angular Content Service
Dev By RayRay
Dev By RayRay

Posted on • Updated on • Originally published at hasnode.byrayray.dev

The Fastest Way To Build Lightweight Angular Content Service

In the typical Angular applications, we use a lot of titles, labels, headers, and more content. But if you need a way to put those content elements in one place, you need something like a dictionary. It's a combination of small words and more extensive sentences.

Some applications need multiple languages, but others need one language but have loads of content to re-use. In this article, I want to show you the fastest way to create a content (some call it a dictionary) Service for your Angular application.

If you need a content service with multiple languages, I highly recommend NGX-Translate. This package offers a simple API and Pipe mechanism to re-use pieces of content but also supports multiple languages.

divider-byrayray.png

Result

If you don't like reading, check out my example on StackBlitz and copy-and-paste it 😆.

Create A Content Service

The simplest and fastest way to create Angular Services is by using the Angular CLI.

ng generate service services/content
Enter fullscreen mode Exit fullscreen mode

By running this command, you will generate an Angular Service, automatically added to the app.module.ts file. If your project has different settings for the CLI, it could appear in another Angular Module.

Now the Content Service looks like this.

import { Injectable } from '@angular/core';

@Injectable({
   providedIn: 'root'
})
export class ContentService {
   constructor() {}
}
Enter fullscreen mode Exit fullscreen mode

divider-byrayray.png

Create A JSON Dictionary File

You need to create a dictionary file to put in all your titles, labels, and other content. Please put it in a place that works best for your application.

I create a dictionary folder where I make the general.dictionary.json file, but I can have more dictionary files there.

The content I put in there looks like this.

{
   "pages" : {
       "home": {
            "title" : "Home",
            "name" : "Company name"
        }
   }
}
Enter fullscreen mode Exit fullscreen mode

You can create any structure you like; it's up to you what works best.

divider-byrayray.png

Prepare Content Service For Re-usability

We start with creating a private property cache$ where we make a BehaviourSubject. We do this because we can subscribe to this BehaviourSubject from any place in the application. And the best part is, when a content item is being updated, it will automatically be updated everywhere.

private cache$: BehaviorSubject<any> = new BehaviorSubject(null);
Enter fullscreen mode Exit fullscreen mode

If you wonder what the difference is between different Subjects, please check this post "When Use RxJS Subject, BehaviourSubject, ReplaySubject, AsyncSubject, or Void Subject in Angular"

The next step is importing the dictionary file on the top.

import content from '../dictionary/general.dictionary.json';
Enter fullscreen mode Exit fullscreen mode

In the constructor of the Service, we want to make sure that if the BehaviourSubject is null, we need to add the content from the dictionary file.

constructor() {
     if (this.cache$.getValue() === null) {
         this.cache$.next(content);
     }
}
Enter fullscreen mode Exit fullscreen mode

Now we need a method that exposes the BehaviourSubject with its content to the subscribers. We do that by returning the cache$ property. The return type of the method is any for this case because you don't have to type the structure of your dictionary. But if you want to, you can do it.

public content(): BehaviorSubject<any> {
    return this.cache$;
}
Enter fullscreen mode Exit fullscreen mode

For making the Service great for usage in your HTML templates, we can expose the content() method with the .getValue() method chained to it.

public value(): any {
     return this.content()?.getValue();
}
Enter fullscreen mode Exit fullscreen mode

Now we have everything in our Service to make it usable. The complete code of the Service looks like this. Simple right 😉.

import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs'
import content from '../dictionary/general.dictionary.json'

@Injectable({
    providedIn: 'root'
})
export class ContentService {
    private cache$: BehaviorSubject<any> = new BehaviorSubject(null)

    constructor() {
        if (this.cache$.getValue() === null) {
            this.cache$.next(content)
        }
    }

    public content(): BehaviorSubject<any> {
        return this.cache$
    }

    public value(): any {
        return this.content()?.getValue()
    }
}

Enter fullscreen mode Exit fullscreen mode

divider-byrayray.png

Use The Content Service In The Content

I guess you know how to make an Angular Component. The CLI is my favorite way to do it. For example, you generate a HomepageComponent.

ng generate component components/homepage
Enter fullscreen mode Exit fullscreen mode

If you have an Angular Component for yourself, it's fine.

First, we need to import the ContentService into our Component and expose it via the constructor.

import { Component } from '@angular/core';

@Component({
    selector: 'homepage',
    templateUrl: './homepage.component.html',
    styleUrls: ['./homepage.component.scss']
})
export class HomepageComponent {
    constructor(private contentService: ContentService) {}
}

Enter fullscreen mode Exit fullscreen mode

Now we want to expose the content from our ContentService to the HTML template. We create a content property in our Component and add the value via the constructor.

import { Component } from '@angular/core';

@Component({
    selector: 'homepage',
    templateUrl: './homepage.component.html',
    styleUrls: ['./homepage.component.scss']
})
export class HomepageComponent {
    public content: any = null
    constructor(private contentService: ContentService) {
        this.content = this.contentService.value()
        console.log('content:', content)
    }
}

Enter fullscreen mode Exit fullscreen mode

Via the console.log, you can test if everything works as expected.

Now add the title from our dictionary file in the HTML template using the ContentService.

<header>
     <h1>{{content?.pages?.home?.title ?? 'title'}}</h1>
</header>
Enter fullscreen mode Exit fullscreen mode

In the example, you can see that we add an expression to the template. In that expression, we are using the nullish collision technique. We do that, so we don't get error's when the property is not in the dictionary file. In this case, it just shows you "title". If the value is available, it will deliver the value.

divider-byrayray.png

Resources

Code Example in StackBlitz

Code Example in Github

GitHub logo devbyray / angular-content-dictionary-service

Created with StackBlitz ⚡️

Angular Content Dictionary Service

How to build a super simple Content / Dictionary Service in Angular? Check the blogpost on the platform you like:

If you found this valuable, please support me by sharing the blogpost. Want to support me with 💰 check my HashNode Sponsor page 🤗.

Edit on StackBlitz ⚡️

divider-byrayray.png

Conclusion

Now you have a straightforward Content Service in Angular without using an external package. So it's lightweight and super fast, and that is the best thing about it. Often, we may be thinking too complicated, but all we need is something simple.

Hopefully, this helps you build great Angular applications that are easy to maintain.

divider-byrayray.png

Thanks!

hashnode-footer.png
*I hope you learned something new or are inspired to create something new after reading this story! 🤗 If so, consider subscribing via email (scroll to the top of this page) or follow me here on Hashnode.
*

Did you know that you can create a Developer blog like this one, yourself? It's entirely for free. 👍💰🎉🥳🔥

If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a DM on Twitter @DevByRayRay when you want to keep it private. My DM's are always open 😁

Discussion (1)

Collapse
aliciameyer profile image
AliciaMeyer

thanks for taking time to discussion such informative and valuable post with us . i appreciate your work . पति-पत्नी में झगड़ा करवाने का टोटका