Tips for obtaining a customizable environmental variable document in an angular production build

The constants service I have maintains all the necessary constants for the application, such as the base URL of the backend.

export class ConstantsService {
  public BACKEND_URL = 'http://10.0.27.176:8000/';
}

This setup is not very flexible because once the project is built, the BACKEND_URL cannot be changed. I need a solution where I can export the BACKEND_URL from a file that is included in the production build, allowing me to modify it post-build as well.

To address this limitation, I tried:

import {environment} from '../environments/environment.prod';
...
export class ConstantsService {
  public BACKEND_URL = environment.url;
}

environment.prod.ts

export const environment = {
  production: true,
  url: 'http://10.0.27.176:8000/';
};

However, the issue I encountered was that the environment.prod.ts file was not present in the build.

If anyone could suggest a way for me to achieve this goal, I would greatly appreciate it.

Edit: Below is my prod build output. The environment.prod.ts file is missing:

Date: 2018-09-11T11:52:10.945Z
Hash: 96c48ccf441d2f7a204f
Time: 9301ms
chunk {scripts} scripts.3af8bf49d802296d8ab1.js (scripts) 174 kB [rendered]
chunk {0} 0.d9c510e0e0d04dde4c78.js () 1.27 kB [rendered]
chunk {1} runtime.a18a7eb7c080a20cb142.js (runtime) 1.84 kB [entry] [rendered]
chunk {2} styles.0260add3f34224e145b6.css (styles) 5.58 kB [initial] [rendered]
chunk {3} polyfills.92108b287fe28032870b.js (polyfills) 59.6 kB [initial] [rendered]
chunk {4} main.4bbca11d5e8a6cdb36c0.js (main) 316 kB [initial] [rendered]

Answer №1

When managing multiple environments, it's crucial to have a system in place that allows for easy configuration editing without the need to rebuild the entire app.

This is especially important in enterprise settings where streamlined deployment processes and consistent build numbers are key. It's also useful when hosting the same app in various locations, such as private cloud scenarios where a one-size-fits-all approach isn't suitable.

To achieve this, we utilize Angular's APP_INITIALIZER to load environment-specific variables during app startup for data retrieval.

For more information, you can refer to the documentation at: https://angular.io/api/core/APP_INITIALIZER

We typically define the URL for fetching data by convention, dropping a .json file with environment-specific settings in the /assets/config/env.json path to be loaded by the initializer.

Answer №2

Have you compiled using the --prod flag? Verify your build settings to ensure that environment.ts is correctly replaced with environment.prod.ts

Answer №3

When you develop a class, it's essential to instantiate it.

For example, here's what it could look like:

export const settings = {
  isProduction: true,
  ...new ConfigService('http://10.0.27.176:8000/')
};

export class ConfigService {
  constructor(public SERVER_URL: string) {}
}

It's important to understand that constants in programming mean that the memory reference of a variable cannot be changed. For instance, if you do:

const y = 1;
y = 2; // This would throw an error

However, when dealing with objects, you are modifying a single memory reference. So technically, you can do something like this (even though it's not recommended):

expont const settings = {
  isProduction: false
}

settings.isProduction = true;

To address your query fully, environment files come into play during the build process of your application. It is advisable to always import the default one (environment.ts).

During the build phase, you can specify which environment file to use using command line parameters.

In Angular 5:

ng build --env prod

In Angular 6:

ng build -c prod

This allows you to switch out the default environment file with the desired one. While prod is a standard environment, you have the flexibility to create additional ones in your angular[-cli].json configuration file.

Answer №4

I couldn't find a solution for what I needed, so I took matters into my own hands.

To start, create two files, config.js and config.prod.js, in your src folder.

var BASE_API_URL = 'X';

Next, modify the angular.json file by adding the following code snippet to the appropriate environment's fileReplacements array:

              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                },
                {
                  "replace": "src/config.js",
                  "with": "src/config.prod.js"
                }
              ],

Add src/config.js to the assets array in the angular.json file as well:

            "assets": [
              "src/assets",
              "src/config.js",
              "src/Web.config"
            ],

Insert

<script src="config.js"></script>
into your index.html file.

Lastly, build the project. You should now have an editable config.js file in the dist folder.

Answer №5

It is recommended to import from environment.ts, which can be swapped out at build time for different configurations.

To utilize environment.prod.ts, you can either execute ng build --prod or

ng build --configuration=production
. In your angular.json file, you will find the following section:

"configurations": {
    "production": {
      "fileReplacements": [
        {
          "src": "src/environments/environment.ts",
          "replaceWith": "src/environments/environment.prod.ts"
        }
      ],
      "optimization": true,
      "outputHashing": "all",
      "sourceMap": false,
      "extractCss": true,
      "namedChunks": false,
      "aot": true,
      "extractLicenses": true,
      "vendorChunk": false,
      "buildOptimizer": true
    }
  }

You can also create custom configurations. For instance, if you have an environment.test.ts file, you could use it like this:

    "test": {
      "fileReplacements": [
        {
          "src": "src/environments/environment.ts",
          "replaceWith": "src/environments/environment.test.ts"
        }
      ],
      "optimization": false,
      "outputHashing": "none",
      "sourceMap": false,
      "extractCss": false,
      "namedChunks": false,
      "aot": false,
      "extractLicenses": false,
      "vendorChunk": false,
      "buildOptimizer": false
    }

In your environment.test.ts file -

export const environment = {
  production: false, // This way, you do not need to enable production mode during development
  url: 'http://10.0.27.176:8000/';
};

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

Attempt to resend HTTP requests using Angular Interceptor exclusively upon user's manual action of clicking a button

I have implemented the Angular HttpInterceptor to handle errors in my Http requests. When an error occurs, except for 401, I show a popup modal with two buttons ('Close' and 'Retry'). However, I am struggling to understand how to retry ...

I am looking to display data in Angular based on their corresponding ids

I am facing a scenario where I have two APIs with data containing similar ids but different values. The structure of the data is as follows: nights = { yearNo: 2014, monthNo: 7, countryId: 6162, countryNameGe: "რუსეთის ...

Enter the quiz that starts counting down as soon as you open it

Is there a way to develop a web application that can send emails to specific users with a link that expires in 3 days? When the user clicks on the link before it expires, a new browser window/tab will open with personalized questions and a countdown timer ...

Patience is key as we anticipate the promise's response to fill out the

Hello, I am currently developing an angular/typescript application and I have been researching about promises. However, I am still struggling to fully understand it. I would greatly appreciate your assistance. I have a function called getUserById() which ...

Derive a data type from a parameter passed to a function defined within an interface

I am working with a function defined in an interface as shown below: interface UseAutocompleteReturnValue { ... getRootProps: (externalProps?: any) => React.HTMLAttributes<HTMLDivElement>; } Within my interface, I aim to create a prop named rootP ...

Tips for transferring JSON data into an array in Angular

How can I pass JSON data retrieved from an API into an array and then display that information in my template? I'm not sure how to accomplish this task. An error is appearing on my console, you can view it here. This is my TypeScript file: this.api. ...

We're sorry, the request was blocked due to a missing Access-Control-Allow-Origin header

Recently, while working on a blog application with the front end in react + typescript and backend in go iris, I encountered an issue when trying to fetch blog content using a get request. The backend was running on localhost:5000 and the node at localhost ...

Issue with dependencies: Incorrect value passed to `ts.resolveTypeReferenceDirective` causing a problem

This issue is really frustrating me. I'm currently working on this repository. Everything seems to be fine on the client side, but when it comes to the server side, I encountered the following problem: MacBook-Pro$ yarn dev yarn run v1.22.19 warning . ...

What is the best approach for managing multiple post requests in Angular?

Currently, in my Angular 12 and NestJS project, I am facing a challenge where I need to synchronize approximately 3000 items from an external API into my application's database. However, during the process of submitting the request, I encounter variou ...

What is the best way to transition from using merge in a pipe in v5 to v6?

Currently, I am following the conversion guide found here and I am attempting to convert the merge function used in a pipe according to this guide. However, after making the changes, it does not work as expected. This is the code snippet I am using to exp ...

What could be causing my D3.js stacked bar chart to show inaccurate results?

I'm encountering some challenges while creating a stacked bar chart in d3.js. The current appearance of my chart is depicted here (developed with D3.js): https://i.sstatic.net/G6UA6.png However, I aim to achieve a design similar to this one (crafted ...

Exploring the representation of recursive types using generic type constraints

Is there a way to create a structure that can handle recursive relationships like the one described below? I am looking to limit the types of values that can be added to a general container to either primitive data types or other containers. Due to limit ...

The authService is facing dependency resolution issues with the jwtService, causing a roadblock in the application's functionality

I'm puzzled by the error message I received: [Nest] 1276 - 25/04/2024 19:39:31 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AuthService (?, JwtService). Please make sure that the argument UsersService at index [0] is availab ...

Setting the initial selection in an Angular 2 Select Component

My goal is to develop a select component wrapper in Angular 2 using ngModel. Although the events work correctly once the selection changes, I am facing an issue with setting the initial selection when it's first rendered. Here is the code for my comp ...

Creating an instance of a class using a class decorator, with or without the 'new'

Seeking alternatives to creating class instances without using the new keyword in TypeScript, I came across this excellent solution that works seamlessly in JavaScript. The code found in the repository mentioned https://github.com/digital-flowers/classy- ...

What is an example of an array attribute within a generic class?

In my typescript code, I have created a generic class with two properties like this - export class WrapperModel<T>{ constructor(private testType: new () => T) { this.getNew(); } getNew(): T { return new this.testType ...

Pattern matching for a single string and a number using regular expressions

I'm a beginner with regex and I need help creating a validation pattern for numbers and exactly one of the following letters: M, m, T, t, B, or b. Here's what I've tried so far: /^\d*|(M|m|T|t|B|b){1} However, I haven't been succ ...

Error in Cordova integration with Razorpay [RazorPayCheckout not found]

I'm encountering an issue where I'm getting a "RazorPayCheckout is not defined" error. I've searched on StackOverflow but couldn't find any helpful answers. Can someone please assist me with this? Thank you in advance. app.component.ht ...

Retrieving the chosen option from a personalized drop-down element

I have been working on a project using Angular 2, where I created a dropdown component with the following code: @Component({ selector: 'dropdown', template: ` <div class="row" > <div class="col-sm-3"> ...

Angular CLI - exploring the depths of parent-child component communication

My issue revolves around accessing the 'edit' method of a child component using @ViewChild, but for some reason it's not functioning as expected. Where could I possibly be going wrong? Here are the console logs: https://i.sstatic.net/wvpVN ...