Setting up Angular using a JSON configuration file with the help of Webpack

My Angular application is set up to use a JSON file. Originally, I was loading it with an HTTP GET request, but more recently I decided to incorporate it directly by enabling JSON support in TypeScript using a Definition file:

declare module "*.json" {
    const value: any;
    export default value;
}

After that, I started importing it whenever needed:

import * as configuration from '../config.json';

This method works well; the variable configuration holds the JSON object itself.

The issue arises when I package the application with Webpack and want the JSON file to be included in the package separately, not bundled with other files. In other words, config.json should exist as its own individual file within the package rather than being combined with other assets.

I attempted to achieve this using utilities like file-loader and move-file-loader:

module: {                                                                    
    rules: [  
    // ...  
    {                                                                        
       test: /\.json$/,                                                       
       loader: 'file-loader?name=[name].json'                                 
    }                                                      
    // OR                                                                    
    {                                                                
        test: /\.json$/,                                                     
        loader: "move-file-loader?name=[name].json!json-loader"              
    }
    // ...
    ]
}

While this approach successfully prevents the JSON file from being merged into the bundle and places it where intended within the package, it also causes the configuration variable to represent the relative path to the JSON file, such as "./config.json", instead of holding the JSON object directly.

Any insights or suggestions on why this behavior might occur?

Answer №1

It appears that the file-loader emits a path to the location where the file was loaded, rather than the actual content of the file itself. Therefore,

import * as config from '../config.json';

converting config into a string that contains the file path is the correct approach.

Regarding the move-file-loader issue, when using it in conjunction with json-loader, the "moved" file actually contains a TypeScript module definition. It seems to still load a bundled version of the file instead of the "copied" version.

Based on these observations, I have devised the following solution: Firstly, we will copy JSON files using file-loader in the Webpack configuration:

module: {                                                                    
    rules: [  
    // ...  
    {                                                                        
       test: /\.json$/,                                                       
       loader: 'file-loader?name=[name].json'                                 
    }
    // ...
    ]
}

Next, we will import the file path emitted by file-loader using TypeScript's require syntax

const configFile = require('../config.json');

This method of importing does not necessitate the presence of the JSON definition file mentioned in my initial query.

Finally, we can retrieve the file from its file-loader path via an HTTP GET request:

http.get(configFile).map(res => res.json()).catch((error: any): any => {
    // ...
}).subscribe(config => {
    // ...
});

where config represents the parsed contents of the JSON file.

I am holding off marking this as the definitive answer for now, as there might be a way to achieve this without relying on HTTP requests.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting Jqgrid Keyboard Navigation Problem

Here is a link to the jsfiddle code snippet. Upon adding jQuery("#grid").jqGrid('sortableRows'); into my JavaScript code, I encountered an issue where keyboard navigation no longer worked after sorting rows Below is the JavaScript code snippet: ...

the script is run only one time

I have developed a unique web component and incorporated it in two distinct sections like this. <div class="sub_container"> <label>Users in Debt</label> <input placeholder="Search by user name" class="input_style ...

There seems to be an issue with JavaScript functionality when implementing Bootstrap 5.3

Struggling with building a website on Visual Studio Code using Bootstrap 5.3. The functions like buttons not expanding and carousel not rolling are not working. Being a beginner, I'm finding it hard to understand why :( Has anyone encountered this is ...

Breaking apart a mesh using THREE.js

Can a single THREE.Mesh be divided into multiple meshes? For instance, can a mesh with 2,000,000 polygons be split into 2,000 meshes each with 1,000 polygons? Edit: Realistically, it may not be possible to retain the exact same number of polygons/vertice ...

Learn how to effectively deserialize a JSON string with an array into a specific class using GSON

I need help on how to serialize and deserialize this specific JSON format into a Java class. Anyone have any code samples or suggestions? [ { "topic": "this is my topic" }, [ { "name": "John" }, { ...

NextJS does not support the rendering of the map function

Currently, I am getting acquainted with NextJS by creating a basic blog. I have successfully passed the data through props and can see it logged in the console within the map function. However, I am facing an issue where the HTML content does not display i ...

Object in motion from left to right

For my game, I am planning to introduce obstacles that move from left to right across the <div id="outline"></div>. I have implemented a solution using setInterval(){...} and .animate(), which works well initially. However, after some time, it ...

Is it possible to retrieve browser history from Google Chrome using Node.js on a Windows operating system?

I'm currently developing a personal electron app for managing my lifestyle. One of the key features is controlling my daily internet browsing through the app. I am aiming to integrate my Chrome history into the electron app. Could someone recommend a ...

My HTML components are not showing alert messages at the top as expected

My application's alert message is supposed to stay on top of all other HTML elements as the page scrolls. However, it seems to be going behind certain components instead of staying on top like it should. This issue is puzzling because all components u ...

The functionality of Protovis JavaScript is not supported within a dropdownlist's onchange event

I encountered an issue where one block of code works fine on its own, but when combined with another block, only one of them functions properly. The problem arises when I try to invoke a method from a dropdownlist using the onchange event, especially afte ...

Efficient techniques for developing lazy-loading ajax services

What are some efficient ways to create lazy ajax services in angular-js? For instance, I need a resource that returns a promise such as: angular.module('MyModule',[]) .factory('myService', function() { return { getData: fun ...

How to Retrieve the Current Item in *ngFor Loop Using TypeScript in Angular 4

In my JSON file, I have an array containing 5 people. Each person in the array has a list of items associated with them. In my HTML code, I am using *ngFor to iterate over the people and display their names. Additionally, I want to display the total sum of ...

I pressed the button but the globalCompositeOperation isn't working as expected. How can I make it function correctly to achieve the desired output like the second canvas?

<!DOCTYPE html> <html> <head> <title>Canvas Compositing Tutorial</title> </head> <body> <canvas id="myCanvas" width="200" height="200" style="border: 1px solid"></canvas> <br> <butt ...

Ways to extract tar data from a hexadecimal representation

After making a RESTAPI call to an endpoint, I was expecting to receive .tar contents. However, what I received appears in hexadecimal format as: <Buffer 4d 4d 00 2a 00 00 00 08 00 13 01 00 00 03 00 00 00 01 01...... The function connectForTar demonstra ...

Using Vue to dynamically bind the source of an HTML audio element and disable it

For a school project, I am creating a small website that sells hip hop beats using Vue.js. One of the pages I'm working on allows users to preview a beat and make a purchase. To enable beat previews, I have included an HTML audio tag. The data for eac ...

Retrieve a collection of composite entities using Jersey ClientResponse

I am attempting to retrieve a List of entities using Jersey RESTful API (both Server and Client). UserRESTClient client = new UserRESTClient(); ClientResponse response = client.getUsersByType(ClientResponse.class, String.valueOf(userType)); List<User&g ...

How can Angularjs code be properly enclosed within a closure?

My question revolves around a basic application that I have outlined: Angular scope not affecting ng-show as expected The issue at hand is that my application exposes global variables, which is far from ideal. I attempted to enclose the AngularJS code in ...

display upcoming schedule and time

How can I display the future date and time in the respective field components? See below for a sample code snippet: require([ "dojo/_base/lang", "dijit/registry", "dojo/ready", "dijit/form/TimeTextBox", "dojo/parser" ], function(lang, registry, ready ...

What is the best way to access the second item using getByRole in React Testing Library when there is no specific name?

I am familiar with using the name option to select the first item here, but how can I go about selecting the second item if it does not have a name identified? -------------------------------------------------- button: Enter "Go": ...

Managing Millisecond Precision in Timestamps with ODP.net

I am currently utilizing ODP.net to fetch some data from Oracle. In a specific dataset, there is a field of the type Timestamp. Despite my efforts to convert it to DateTime or string, it consistently truncates the milliseconds. Here is an example of the d ...