Using JSON in Angular
bob.ts
Posted on August 9, 2021
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,
...
}
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": "..."
}
}
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,
...
};
Configuration
Using the following in a config.json
file ...
{
"features": {
"enableKonami": true,
"enableTheme": true,
...
"useLocalJSON": false
}
}
The file can then be imported like this ...
import config from '@core/constants/config.json';
And used like this ...
if (config.features.useLocalJSON === true) {
...
}
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;
...
}
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",
...
}
}
The file can then be imported like this ...
import language from '@core/constants/language.json';
And used like this ...
@Component({
...
})
export class CardFunctionalityComponent implements OnInit {
...
selectedLanguage: string = 'english';
language: any = language[selectedLanguage];
...
}
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];
}
};
The hostnameService.get
does something like this ...
get = (_window) => _window?.location?.hostname;
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" ]
}
}
Now, looking at this it is clear that if we have data coming in such as ...
[
{ "selected": false, "id": "1", "lastname": "Fornal", "firstname": "Bob" },
...
]
We can ...
- Set the order when displayed on a table
- Enable proper sorting of the data
- Display proper column names
- Decide whether to display the column or not
- 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.
Posted on August 9, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.