Using JSON in Angular

rfornal

bob.ts

Posted on August 9, 2021

Using JSON in Angular

Being able to import and process JSON files provides a whole host of configuration options, as well as providing a means of capturing data locally for development purposes.

When I started using this pattern, I was looking for a means to provide basic configuration (i.e. Feature Flags). The process quickly evolved into ...

  • Authorization
  • Configuration (Feature Flags)
  • Language
  • Host Names
  • Core Structures (think titles matching data keys)

But first, I needed to be able to read these files.

Importing and Reading JSON files

In the tsconfig.json file I added the "resolveJsonModule": true configuration option under the compilerOptions key:

{
  "compileOnSave": false,
  "compilerOptions": {
    ...
    "resolveJsonModule": true,
    ...
}
Enter fullscreen mode Exit fullscreen mode

Additionally, I learned that I can read a JSON file that is in the assets folder via an http.get request. This provided a whole host of options for development purposes.

Now, let's look at some code.

Authorization

Basically, I built several keys and associated information for ...

  • localhost
  • Development
  • Stage
  • Production

The JSON file looks something like this ...

{
  "localhost": {
    "issuer": "https://identity ....",
    "clientId": "..."
  },
  "application.apps.cf.np.gc ...": {
    "issuer": "https://identity ...",
    "clientId": "..."
  },
  "application-stg.apps.cf.gc ...": {
    "issuer": "https://identity ...",
    "clientId": "..."
  },
  "application-ui.apps.cf.gc ...": {
    "issuer": "https://identity ...",
    "clientId": "..."
  }
}
Enter fullscreen mode Exit fullscreen mode

Additionally, I added code to look at the base URL and determine which of these "keys" to use.

In the app-routing.module.ts, the code added looks like this ...

import authnames from '@core/constants/auth.json';

const hostnameService = new HostnameService();
const hostname = hostnameService.get(window);

if (authnames[hostname] === undefined) {
  console.error('Issue with auth.json, hostname: ', hostname);
}

const authConfig = {
  issuer: authnames[hostname].issuer,
  clientId: authnames[hostname].clientId,
  ...
};
Enter fullscreen mode Exit fullscreen mode

Configuration

Using the following in a config.json file ...

{
  "features": {
    "enableKonami": true,
    "enableTheme": true,
    ...
    "useLocalJSON": false
  }
}
Enter fullscreen mode Exit fullscreen mode

The file can then be imported like this ...

import config from '@core/constants/config.json';
Enter fullscreen mode Exit fullscreen mode

And used like this ...

if (config.features.useLocalJSON === true) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

config in this sense can be included in a component, as such, to be used in HTML.

@Component({
  ...
})
export class CardFunctionalityComponent implements OnInit {
  ...
  features: any = config.features;
  ...
}
Enter fullscreen mode Exit fullscreen mode

Language

Using the following in a language.json file allows for quick switching between languages, and puts all strings in one location for easy management ...

{
  "english": {
    "config": "Configuration",
    "header": "Header",
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

The file can then be imported like this ...

import language from '@core/constants/language.json';
Enter fullscreen mode Exit fullscreen mode

And used like this ...

@Component({
  ...
})
export class CardFunctionalityComponent implements OnInit {
  ...
  selectedLanguage: string = 'english';
  language: any = language[selectedLanguage];
  ...
}
Enter fullscreen mode Exit fullscreen mode

Host Names

getURL = (key: string): string => {
  if (this.useLocalJSON) {
    return hostnames.localJSON.BASE + hostnames.localJSON[key];
  } else {
    let hostname: string = this.hostnameService.get(window);
    return hostnames.HOSTNAMES[hostname] + hostnames.ROUTES[key];
  }
};
Enter fullscreen mode Exit fullscreen mode

The hostnameService.get does something like this ...

get = (_window) => _window?.location?.hostname;
Enter fullscreen mode Exit fullscreen mode

I did this simply to make the code more testable.

Core Structures

Core structures are a but harder to define.

I use these to define things like:

  • Headers for table columns that match the expected data.
  • Order of the columns.
  • Visibility of individual columns (allowing them to be displayed or not).

Let's look at some code to see where this is going.

{
  "ORDER": [
    "selected",
    "id",
    "lastname",
    "firstname"
    ...
  ],

  "SORTING": {
    "id": "number",
    "lastname": "string",
    "firstname": "string",
    ...
  },

  "COLUMNS": [
    { "id": "selected", "name": "Selected", "isActive": false },
    { "id": "id", "name": "Event Id", "isActive": true },
    { "id": "lastname", "name": "Last", "isActive": true },
    { "id": "firstname", "name": "First", "isActive": true },
    ...
  ],

  "DEFAULT": {
    "defaultSortParams": [ "lastname", "firstname" ],
    "defaultSortDirs": [ "asc", "asc" ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, looking at this it is clear that if we have data coming in such as ...

[
  { "selected": false, "id": "1", "lastname": "Fornal", "firstname": "Bob" },
  ...
]
Enter fullscreen mode Exit fullscreen mode

We can ...

  1. Set the order when displayed on a table
  2. Enable proper sorting of the data
  3. Display proper column names
  4. Decide whether to display the column or not
  5. Enable default sorting options

This is a lot of functionality that can be packed into a structure file.

Summary

Being able to import JSON files can make development easier, more efficient, and overall a better experience when used correctly.

Being able to import and process JSON files can make development easier, more efficient, and overall a better experience when used correctly. It provides a whole host of configuration options, as well as providing a means of capturing data locally for development purposes.

💖 💪 🙅 🚩
rfornal
bob.ts

Posted on August 9, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Using JSON in Angular
json Using JSON in Angular

August 9, 2021