DEV Community

Cover image for Using JSON in Angular
bob.ts
bob.ts

Posted on

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.

Top comments (0)