Issue with Angular 8: discrepancy between the value utilized in component.html and the value stored in component.ts (Azure application service)

Encountering a peculiar behavior in one of my Angular applications. In the component.html file, I aim to display "UAT" and style the Angular mat elements with a vibrant orange color when in UAT mode, while displaying them in blue without any mention of UAT (aka PROD) otherwise.

Everything seems fine locally, but once deployed to Azure, things get confusing. Here's an excerpt from my code:

Within my Angular solution, there is an env.json file structured as follows:

{
"production": false,
"isTestEnvironment": false,
}

In VSTS, after building the app once, it is utilized for all deployments. For UAT deployment, "isTestingEnvironment" is set to "true" before shipping it off to Azure. Similarly, for production deployment, "production" is set to "true" and "isTestingEnvironment" to "false" before shipment.

To extract this env.json, something like this is used in app.module.ts:

const appInitializer = {
 provide: APP_INITIALIZER,
 useFactory: configFactory,
 deps: [AppConfig],
 multi: true
};

The appInitializer is then registered in the providers section, and the AppConfig injectable looks like:

import {Injectable} from '@angular/core';

import {HttpClient} from '@angular/common/http';

@Injectable()
export class AppConfig {
 public config: any;

 constructor(private http: HttpClient) {}

 public load() {
  return new Promise((resolve, reject) => {
   this.http.get('env.json').subscribe((p: string) => {
    this.config = p;
    resolve(true);
   });
  });
 }
}

In the component's constructor, the isTestingEnvironment is retrieved first:

this.isTestEnvironment = appConfig.config.isTestEnvironment;

Upon console.log, the values appear correct - true for UAT, false for PROD, and matching the value in the local environment even during hot changes while ng serve is running.

Despite the well-formed env.json file being deployed (as confirmed using kudu/powershell), the following line in component.html causes issues:

<h5 style="margin: auto;" *ngIf="isTestEnvironment">UAT</h5>

Regardless of whether isTestingEnvironment is true or false moments earlier according to the console log, "UAT" always appears in UAT and PROD modes. Strangely, this works perfectly during local debugging sessions using Visual Studio Code (1.42.1) and Node.js (v10.18.1).

At this juncture, Angular seems to equate true with false, leaving me utterly perplexed.

I've verified multiple times that the variable isTestingEnvironment is only set in the env.json file within the Angular solution. It seems like I'm either overlooking something glaringly obvious or there's a serious flaw in my code.

Any assistance on this matter would be immensely appreciated.

Thank you.

Answer №1

After some investigation, I finally uncovered the root cause of the issue.

In summary: The problem stemmed from a VSTS release task known as "Azure App Service Deploy" which converted variables to strings in the "File Transform & Variable Substitution Option" section.

Upon closer inspection of the deployed file, I noticed that a variable that was originally:

{
"isTestEnvironment": true,
}

had been changed to:

{
"isTestEnvironment": "true",
}

when it reached the azure server. This discrepancy led to erroneous checks against the supposed boolean variable, as a non-empty string is considered true in JavaScript.

As a solution, I now use JSON.parse(myVariable) when extracting the variable from the env.json file. I tested this locally and it resolved the issue.

For those utilizing the same release task, be cautious of the conversion of booleans to strings. Our release pipeline variables were not declared with quotation marks around them, simply containing true/false values.

I appreciate the assistance provided in suggesting potential workarounds. Thank you all.

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

I am looking to generate an array with key-value pairs from an object that will be seen in the examination

I have a task that involves configuring a table and creating objects with key-value pairs for each key. type KeyValuePair<T> = {/** ... */}; let userKeyValuePair :KeyValuePair<{id:number,userName:string}>; // => {key:'id',value: ...

Unlocking the Power of Typescript and ReactJS: Maximizing Efficiency with Previous State

I'm encountering difficulties implementing the previous state in React 18 with Typescript version 4.8.3. Here is my refreshToken code and I'm receiving the following error: Value of type '(prev: any) => any' has no properties in c ...

Integrating Angular with Oracle

Exploring the possibility of building applications with Angular/ORDS/Oracle, as I am relatively new to this particular web stack. From what I've gathered so far, it seems like we need a front end, back end, and database in order to create a complete a ...

CORS policy has blocked access to XMLHttpRequest from the origin because the requested resource does not have the 'Access-Control-Allow-Origin' header

I recently built an API project using MVC Core. Everything seemed to be working fine when testing the GET and POST methods with Postman. However, I encountered a CORS error when trying to call these APIs from my Angular App: Access to XMLHttpRequest fro ...

How can the value be accessed when using getElementById in Angular for <mat-select> elements that do not have a value attribute?

Within a loop, I have an element that has a dynamically generated id: <mat-select multiple class="dw-input" [value]="element.txn_type_id ? element.txn_type_id.split(',') : []" id="field-{{element.Name}}-txn_type_id&quo ...

Opening a modal in Angular2+ when selecting an item from ngx-chips (tag-input)

I need to implement a functionality where clicking on a tag in a dropdown should trigger the opening of a modal window in my Angular application. Below is the code snippet related to this feature: <div class="force-to-the-bottom"> <tag-input [ ...

Ways to troubleshoot this issue: encountering error in Angular v11 - The Schematic workflow has encountered a failure

I keep encountering an error whenever I try to generate a new project Command I used: ng new dron (to create the project) Error message: npm ERR! Found: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1767786463746464572f39253 ...

The Angular 4 application is unable to proceed with the request due to lack of authorization

Hello, I am encountering an issue specifically when making a post request rather than a get request. The authorization for this particular request has been denied. Interestingly, this function works perfectly fine with my WPF APP and even on Postman. B ...

How can a TypeScript Angular directive utilize a function?

Recently, I have been following a unique Angular directive TypeScript pattern that I find really effective. The approach involves giving the directive its own isolated scope by creating a new controller. I encountered a scenario where I needed to invoke a ...

Click on a kendo-chip in Angular to copy its content

Can someone assist me in copying the content within a Kendo Chip when clicked in an Angular application? Your help is greatly appreciated. View image here ...

Adding TypeScript to your Vue 3 and Vite project: A step-by-step guide

After setting up my project by installing Vue and Vite using the create-vite-app module, I decided to update all the packages generated by 'init vite-app' to the latest RC versions for both Vue and Vite. Now, I am interested in using TypeScript ...

When trying to generate a popOver in Ionic, an error message "<TypeError: ev.target.getBoundingClientRect is not a function>" may be displayed

I'm currently working on implementing a popover that appears when a mouse click event is triggered. However, I've encountered an issue where the Create() method of the popover gets called upon event activation, but I keep receiving the following ...

Angular time-based polling with conditions

My current situation involves polling a rest API every 1 second to get a result: interval(1000) .pipe( startWith(0), switchMap(() => this.itemService.getItems(shopId)) ) .subscribe(response => { console.log(r ...

Custom "set attribute" feature in TypeScript

One issue I faced was resolved by creating the function shown below : function setProperty<T extends Record<string, string>>(obj: T, key: keyof T) { obj[key] = "hello"; } However, when I tried to compile the code, I encountered an ...

Issue with NgRx Testing: Callback in subscribe method fails to update during testing

I am currently working on testing a component that is responsible for editing shopping list items. Upon first loading, the component receives state values through store.select, which are: editedIngredient: null, editedIngredientIndex: -1 Based on these ...

Angular 2 code test coverage

Looking to calculate the code coverage of my Angular 2 code. Wondering if there are any plugins available for VS Code or WebStorm that can assist with this. My unit testing is done using Jasmine and Karma. ...

Angular service providing components (TypeScript error)

This is my first time trying to dynamically inject components and so far, I've been successful. However, there's an error in Typescript that's bothering me (I don't like having errors in my code). If you want to check out the app, here ...

Combining tuples with their corresponding data types

Trying to define a new type: type Union = [1, "one"] | [1, "first"] | [2, "two"] type GetTuple<T, U> = Extract<T, [U, ...unknown[]]>; type ObjectFromUnion<T extends Union[0] = Union[0]> = { number: T, word: ?? } Looking to utiliz ...

Perfroming unit testing on base class using Jasmine and Angular framework

I have a common base class that I include in every grid component. Currently, I have the specifications for the grid component, but I want to create separate specifications for the base class in its own spec file. The goal is to eliminate redundant code ...

propagate the amalgamation of tuples as an argument

I'm working with a function that returns a union type of tuples. I need to pass this return value to another function that can accept all its forms using the spread operator .... type TupleUnion = readonly [number, number] | readonly [number, number, ...