Full Trust European Hosting

BLOG about Full Trust Hosting and Its Technology - Dedicated to European Windows Hosting Customer

AngularJS Hosting Europe - HostForLIFE.eu :: Custom Directives in the Angular

clock April 3, 2024 09:51 by author Peter

One of the main components of the Angular framework is Angular directives, which are used to attach to the DOM, change elements, and enhance the functionality and structure of HTML.


Predefined directives with an angle

ngStyle, ngClass, ngIf, ngFor, and ngswitch

Why are the custom directives being created?
When developing real-time applications, it's common to need to preserve consistency and reusability while utilizing the same feature repeatedly.

As an illustration
Only allow numbers in the registration form; any text entered by the user will be blocked by the input field.
Make the special directive.

ng g directive Directive/AollwNumber

AllowNumber.ts

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appAllowNumber]'
})
export class AllowNumberDirective {

 // Allow numbers.
 private regex: RegExp = new RegExp(/^\d+$/);

 // Allow key codes for special events. Reflect :
 // Backspace, tab, end, home
 private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', 'ArrowLeft', 'ArrowRight', 'Delete'];

 constructor(private el: ElementRef) {
 }

 @HostListener('keydown', ['$event'])
 onKeyDown(event: KeyboardEvent) {
    debugger
     const selecetdText = window.getSelection().toString();
     // Allow Backspace, tab, end, and home keys
     if (this.specialKeys.indexOf(event.key) !== -1) {
         return;
     }

     let current: string = this.el.nativeElement.value;

     if(selecetdText != "" && current.indexOf(selecetdText) !== -1){
         current = current.slice(0,current.indexOf(selecetdText));
     }
     // We need this because the current value on the DOM element
     // is not yet updated with the value from this event
     let next: string = current.concat(event.key);

     if (next && !String(next).match(this.regex)) {
         event.preventDefault();
     } else if (event.currentTarget['max'] != "undefined" && event.currentTarget['max'] != "" && event.currentTarget['max'] != null && !(Number(event.currentTarget['max']) >= Number(next))) {
         event.preventDefault();
     }
     if(event.currentTarget['min'] != "undefined" && event.currentTarget['min'] != "" && event.currentTarget['min'] != null && !(Number(event.currentTarget['min']) <= Number(next)) ){
         event.preventDefault();
     }

 }
 /**
  * This is for restrict paste value in input field
  * @param e
  */
 @HostListener('paste', ['$event']) blockPaste(e: KeyboardEvent) {
     e.preventDefault();
 }

}


Register the directive App module
After the creation of the directive, this is required to be registered in the root directive module or app module.

Decore directive in the Input Field




AngularJS Hosting Europe - HostForLIFE.eu :: Data Binding in Angular

clock March 26, 2024 07:34 by author Peter

Data binding serves as a link between the template (representing the view) and the component (which contains the application's logic and data).

In Angular data binding, various types are used to define the direction of data flow between the component and the template (view).

Type of Data Binding

  • One-way Data Binding
  • Two-way Data Binding

One-way Data Binding

Interpolation

Interpolation is a simple and straightforward method for embedding dynamic values into HTML templates. It allows you to show component properties in the view.

Example
//app.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'TodoList';
}

<!-- app.component.html -->
<h1>{{title}}</h1>

Property Binding

Property binding allows you to bind a property of a DOM element to a component property. This way, changes in the component automatically reflect in the view.

Example
//app.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
isDisabled= true;
}

<!-- app.component.html -->
<button [disabled]="isDisabled">Click me</button>

Event Binding
Event binding enables you to respond to user interactions or other events by connecting a component method with a specific event in an HTML template. This two-way link allows for dynamic and interactive user experiences by triggering component functions in response to user actions like clicks, hovers, touches, and other events.

Example
//app.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';

@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
onClick() {
console.log(Hi Welcome!');
}
}


<!-- app.component.html -->
<button (click)="onClick()"> Click me 😊</button>

Two-way Data Binding

Two-way binding combines property and event binding to provide a bidirectional link between a component property and a template input element. This synchronization allows for automated updates in both directions, guaranteeing that changes to the component's properties are reflected in the template and vice versa, eliminating the need for explicit event handling or manual updates. To utilize [(ngModel)], you must import the FormsModule into your module, as it contains the directives required for two-way binding.

Example
//app.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule,FormsModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  text: string = '';
}

<1 -- app.component.html -->

<input [(ngModel)]="text" placeholder="Please enter text here">
<p>the text which you have type: {{ text }}</p>


Data binding is essential for connecting the application's logic with the user interface, offering one-way bindings for efficient data transfer and two-way bindings, exemplified by [(ngModel)], for seamless bidirectional synchronization, streamlining the development of dynamic and interactive web applications.



AngularJS Hosting Europe - HostForLIFE.eu :: Animated Credit Card Design Using Angular

clock March 18, 2024 09:17 by author Peter

To create an aminated credit card form in Angular, alter the app.module.ts file as follows:

Final Screen: Animated Credit Card

Final Screen animated credit card for the sample shown below.

In ngModule

  • declarations: Specifies the components, directives, and pipes that belong to this module. In this case, AppComponent is declared here.
  • imports: Lists other modules whose exported classes are needed by component templates declared in this NgModule. Here, various Angular modules like CommonModule, AppRoutingModule, BrowserAnimationsModule, FormsModule, and ReactiveFormsModule are imported.(CommonModule for Using *ngfor and *ngIf directive, FormsModule, ReactiveFormsModule - to use the form, BrowserAnimationsModule- in the following sample, we used animation module).
  • schemas: This is an array of schema types that should be ignored or not checked for this module. CUSTOM_ELEMENTS_SCHEMA tells Angular to ignore or accept any elements and attributes that are not standard HTML but are custom elements. NO_ERRORS_SCHEMA tells Angular to ignore unknown elements and attributes altogether.
  • bootstrap: Specifies the main component that should be bootstrapped when this NgModule is bootstrapped. In this case, it's AppComponent.

@NgModule({
  declarations: [AppComponent], // Components, directives, and pipes that belong to this NgModule.
  imports: [
    CommonModule, // Provides commonly used directives, pipes, and services.
    AppRoutingModule, // The routing module for the application.
    BrowserAnimationsModule, // Module for providing animations support in Angular.
    FormsModule, // Module for two-way data binding using ngModel directive.
    ReactiveFormsModule // Module for reactive forms support.
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], // Defines the schema to be used for components.
  bootstrap: [AppComponent] // The main component to be bootstrapped when this NgModule is bootstrapped.
})


In (app.component.ts)

  • selector: Defines the HTML tag that will represent this component in other HTML files.
  • encapsulation: Specifies the encapsulation strategy for the component's styles. ViewEncapsulation.None means that the styles defined in the component will affect the entire application without any encapsulation.
  • templateUrl: Points to the external HTML file containing the template for this component.
  • styleUrls: An array of URLs pointing to external style files (like SCSS or CSS) for this component.
  • animations: An array of animation definitions for this component. In this case, it defines an animation trigger named 'flipState' which flips the component around the Y-axis when the state changes from 'active' to 'inactive' and vice versa.

@Component({
  selector: 'app-root', // The CSS selector that identifies this component in a template.
  encapsulation: ViewEncapsulation.None, // Defines how the styles of the component should be encapsulated. 'None' means no encapsulation.
  templateUrl: './app.component.html', // The URL of the template file for this component.
  styleUrls: ['./app.component.scss'], // An array of URLs of the style files for this component.
  animations: [ // An array of animation definitions for this component.
    trigger('flipState', [ // Defines an animation trigger named 'flipState'.
      state('active', style({ // Defines a state named 'active' with a specific style.
        transform: 'rotateY(179deg)' // CSS transformation to rotate the element.
      })),
      state('inactive', style({ // Defines a state named 'inactive' with a specific style.
        transform: 'rotateY(0)' // CSS transformation to rotate the element back to its original position.
      })),
      transition('active => inactive', animate('500ms ease-out')), // Defines a transition from 'active' to 'inactive' state with specific animation.
      transition('inactive => active', animate('500ms ease-in')) // Defines a transition from 'inactive' to 'active' state with specific animation.
    ])
  ]
})

In the below session, continue the app component.

Added the CardDetails object to get the card info, and while clearing, the object was reset to the initial state.
toggleFlip(): If we are entering CVV, only the credit card needs to be animated and show the back card, so here we have set the flip animation trigger we have defined as 'active'
toggleFront(): If we are unfocused CVV input, we need to animate and show the front card, so here we have set the flip animation trigger we have defined as 'inactive'

export class AppComponent {
  isShowBackCard: boolean = false;
  flip: string = 'inactive';
cardDetails:any=
{
  Name:null,
  CardNumber:null,
  CVV:null,
  ExpiryMonth:2,
  ExpiryYear:24
};
  toggleFlip() {
    this.flip ='active';
  }
  toggleFront()
  {
    this.flip =  'inactive';
  }
  constructor() {}
  Clear()
  {
    this.cardDetails=
    {
      Name:null,
      CardNumber:null,
      CVV:null,
      ExpiryMonth:2,
      ExpiryYear:24
    };
  }
  title = 'card-test';
}


In (app.component.html)
Here, we have two sections: one credit card front and back design and form with validation using template-driven forms.

Credit card design
    [@flipState]="flip" we have using the flipstate animation trigger.
    if filpstate is inactive, we will display the front card, and active means we will show the back card.
    the flipstate will set based on focus on cvv input.

<main class="main">
  <div class="content">
    <div>
      <div class="tp-box" [@flipState]="flip">
        <div class="front-card" *ngIf="flip === 'inactive'">
          <p class="card-number">CARD NUMBER</p>
          <p class="card-number">{{!cardDetails.CardNumber? "XXXX-XXXX-XXXX-XXXX" :cardDetails.CardNumber}}</p>
          <div class="info-container row">
            <div class="col-md-9">
              <p class="cardholder-name ">CARD HOLDER NAME</p>
              <p class="cardholder-name">{{!cardDetails.Name? "YYYYYYY YYYYYYYY" :cardDetails.Name}}</p>
            </div>
            <div class="col-md-3">
              <p class="exp-date ">EXPIRY (MM/YY)</p>
              <p class="exp-date ">{{cardDetails.ExpiryMonth}}/{{cardDetails.ExpiryYear}}</p>
            </div>
          </div>
        </div>
        <div class="back-card" *ngIf="flip === 'active'">
          <p class="cvc">{{cardDetails.CVV}}</p>
        </div>
      </div>
      <div class="panel panel-default card-glass">
        <div class="panel-heading no-bg-color">
          <h1 class="or-color">Enter Card Details</h1>
        </div>
        <div class="panel-body">
          <div class="right-payment-sec">
            <form #cardForm="ngForm" autocomplete="off" name="cardForm" (ngSubmit)="cardForm.valid">
              <div class="row">
                <div class="col-lg-12 col-xs-12">
                  <div class="form-group">
                    <label class="no-bg-color" for="name">Name On Card</label>
                    <input type="text" class="form-control no-bg-color"
                      [ngClass]="{ 'has-error': cardForm.submitted && name.invalid }" #name="ngModel" id="name"
                      [(ngModel)]="cardDetails.Name" required autofocus name="name" placeholder="Name On Card">
                    <div *ngIf="cardForm.submitted && name.invalid" class="">
                      <label class="control-label error-message" *ngIf="name.errors?.['required']"><i
                          class="fa fa-times"></i> Required</label>
                    </div>
                  </div>
                </div>
                <div class="col-lg-12 col-xs-12">
                  <div class="form-group">
                    <label class="no-bg-color" for="cardnumber">Card Number</label>
                    <input type="number" class="form-control no-bg-color" #cardnumber="ngModel" id="cardnumber"
                      [(ngModel)]="cardDetails.CardNumber" name="cardnumber"
                      onKeyPress="if(this.value.length==16) return false;" required
                      [ngClass]="{ 'has-error': cardForm.submitted && cardnumber.invalid }"
                      placeholder="XXXX-XXXX-XXXX-XXXX">
                    <div *ngIf="cardForm.submitted && cardnumber.invalid" class="">
                      <label class="control-label error-message" *ngIf="cardnumber.errors?.['required']"><i
                          class="fa fa-times"></i> Required</label>
                    </div>
                  </div>
                </div>
                <div class="col-lg-6 col-md-6 xol-sm-6 col-xs-12 card-infos-container">
                  <label class="no-bg-color" for="expiry">Expiration (MM/YY)</label>

                  <div class="form-group date-container" id="date">
                    <div class="date">

                      <input type="number" class="form-control no-bg-color " placeholder="MM" #expiryMonth="ngModel"
                        [ngClass]="{ 'has-error': cardForm.submitted && expiryMonth.invalid }" id="expiryMonth"
                        [(ngModel)]="cardDetails.ExpiryMonth" name="expiryMonth" [min]="1" [max]="12" required>
                      <input type="number" class="form-control no-bg-color" placeholder="YY" #expiryYear="ngModel"
                        [ngClass]="{ 'has-error': cardForm.submitted && expiryYear.invalid }" id="expiryYear"
                        [(ngModel)]="cardDetails.ExpiryYear" name="expiryYear" [min]="01" [max]="99" required>

                    </div>
                    <div *ngIf="cardForm.submitted && (expiryMonth.invalid||expiryYear.invalid)" class="">
                      <label class="control-label error-message" *ngIf="expiryMonth.errors?.['required']"><i
                          class="fa fa-times"></i> Required</label>
                      <label class="control-label error-message" *ngIf="expiryMonth.errors?.['min']"><i
                          class="fa fa-times"></i> month 01-12 only</label>
                      <label class="control-label error-message" *ngIf="expiryMonth.errors?.['max']"><i
                          class="fa fa-times"></i> month 01-12 only</label>
                      <label class="control-label error-message" *ngIf="expiryYear.errors?.['required']"><i
                          class="fa fa-times"></i> Required</label>
                      <label class="control-label error-message" *ngIf="expiryYear.errors?.['min']"><i
                          class="fa fa-times"></i> Year 01-99 only</label>
                      <label class="control-label error-message" *ngIf="expiryYear.errors?.['max']"><i
                          class="fa fa-times"></i> Year 01-99 only</label>
                    </div>
                  </div>
                </div>
                <div class="col-lg-3 col-md-3 xol-sm-6 col-xs-12">
                  <div class="form-group">
                    <label class="no-bg-color" for="cvv">CCV</label>
                    <input type="number" class="form-control no-bg-color" #cvv="ngModel"
                      [ngClass]="{ 'has-error': cardForm.submitted && cvv.invalid }" id="cvv"
                      [(ngModel)]="cardDetails.CVV" name="cvv" required
                      (focus)="$event.stopPropagation();$event.preventDefault();toggleFlip()"
                      (blur)="$event.stopPropagation();$event.preventDefault();toggleFront()"
                      onKeyPress="if(this.value.length==3) return false;" placeholder="XXX">
                    <div *ngIf="cardForm.submitted && cvv.invalid" class="">
                      <label class="control-label error-message" *ngIf="cvv.errors?.['required']"><i
                          class="fa fa-times"></i> Required</label>
                    </div>
                  </div>
                </div>

                <div class="modal-footer">
                  <div class="form-group">
                    <button type="submit" class="btn btn-primary button-form" style="margin-right: 10px ;">Save</button>
                    <button type="button" class="btn btn-primary button-form" (click)="Clear()">Clear</button>
                  </div>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
</main>


app.component.scss

.background {
    width: 100%;
    height: 47.5vw;
    background-image: url(../assets/Credit-card-bro.svg), linear-gradient(to right, #00e7ff, #634d38);
    background-repeat: no-repeat;
    background-size: cover;
}

.card-glass {
    backdrop-filter: blur(3px) saturate(113%);
    -webkit-backdrop-filter: blur(3px) saturate(113%);
    background-color: rgba(255, 255, 255, 0);
    border-radius: 12px;
    border: 2px solid rgb(123 107 107);
}

input {
    border: 1px solid rgb(123 107 107);
}

.no-bg-color {
    background-color: transparent !important;
    font-size: medium;
    color: #df7017;
}

.or-color {
    color: #df7017;
}

.front-card {
    -webkit-transform: rotateY(0deg);
    -ms-transform: rotateY(0deg);
    transform: rotateY(0deg);
    background-image: url(../assets/1234.png);
    margin-left: 19%;
    // display: flex;
    // flex-direction: column;
    justify-content: space-around;
    border-radius: 8px;

    //  *{
    // margin-left: 1.5rem;
    // margin-top: 10.5rem;
    //  }
    .exp-date {
        font-size: 2rem;
    }

    .card-number {
        font-size: 2rem;
        margin-left: 1.5rem;
    }

    .cardholder-name {
        margin: 0;
        font-size: 2rem;
    }

    .info-container {

        width: 85%;
        // display: flex;
        // justify-content: space-between;
        margin-left: 1.5rem;
        margin-top: 6.5rem;
        font-family: sans-serif;
        font-weight: lighter;
        text-transform: uppercase;
    }

    img {
        width: 20%;
        height: 20%;
    }
}

.back-card {
    background-image: url(../assets/bg-card-back.png);
    display: flex;
    align-items: center;
    justify-content: end;
    -webkit-transform: rotateY(-180deg);
    -ms-transform: rotateY(-180deg);
    transform: rotateY(-180deg);
    margin-left: 19%;
    backface-visibility: hidden;

    p {
        margin-right: 6rem;
        font-size: medium;
    }
}

.back-card,
.front-card {
    background-repeat: no-repeat;
    background-size: cover;
    position: absolute;
    top: 0;
    left: 0;
    width: 447px;
    height: 245px;

    color: whitesmoke;
}

@media screen and (max-width: 768px) {

    .front-card,
    .back-card {
        position: absolute;
        width: 248px;
        height: 136px;
        margin-left: 0;

    }

    .front-card {
        bottom: -2rem;
        left: 1rem;
        z-index: 10;

        .card-number {
            font-size: 1rem;
        }

        .cardholder-name {
            font-size: 0.8rem;
        }

        .exp-date {
            font-size: 0.8rem;
        }
    }

    .back-card {
        top: 2rem;
        right: 1rem;

        p {
            margin-right: 2rem;
            font-size: 0.8rem;
        }
    }
}

.credit-form {
    min-width: 150px;
    max-width: 400px;
    width: 100%;
}

.full-width {
    width: 100%;
}

form {
    width: 100%;
    display: flex;
    flex-direction: column;

    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

    .card-infos-container {

        .date-container {
            width: 47%;

            .date {

                display: flex;
                gap: 1rem;
                width: 100%;

                mat-form-field {
                    width: 40%;
                }
            }
        }
    }

    button {
        height: fit-content;
    }
}

.button-form {
    margin-right: 10px;
    height: fit-content;
    font-size: larger;
}


.tp-box__side {
    width: 100%;
    height: 100%;
    position: absolute;

    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;

    color: #fff;
    text-align: center;
    line-height: 100px;
    font-size: 24px;
    font-weight: 700;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.tp-box {
    position: relative;
    height: 215px;
    z-index: 15;
    margin: 3rem auto;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    -webkit-transform: transform 1s;
    -ms-transform: transform 1s;
    transform: transform 1s;
}



AngularJS Hosting Europe - HostForLIFE.eu :: Reactive Forms In Angular with Practical Example

clock March 5, 2024 08:47 by author Peter

Angular is a popular framework for developing dynamic web apps, and one of its most notable features is its robust forms module. Angular provides two types of forms: template-driven and reactive forms. In this post, we'll look into reactive forms in Angular, including their benefits, how to design them, and how to use them efficiently.


What are the reactive forms? Reactive forms, also known as model-driven forms, are a more adaptable and scalable way to create forms in Angular. Unlike template-driven forms, which essentially specify the form's behavior in the template, reactive forms are defined programmatically by creating form control objects with TypeScript classes.

Key Benefits of Reactive Forms
More control and flexibility: Reactive forms give developers more control over form validation, error handling, and dynamic form controls.

  • Immutable data model: Reactive forms use an immutable data model, making it easier to track changes and manage form states.
  • Better support for complex forms: Reactive forms are well-suited for building complex forms with dynamic form controls and complex validation requirements.
  • Easier unit testing: Since form controls are created programmatically as TypeScript objects, they are easier to unit test compared to template-driven forms.

Creating Reactive Forms
To create a reactive form in Angular, follow these steps:
Import the necessary Angular modules

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

JavaScript
Define the form in the component class

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-contact-form',
  templateUrl: './contact-form.component.html',
  styleUrl: './contact-form.component.css'
})
export class ContactFormComponent {

  contactForm!: FormGroup;

  constructor(private fb: FormBuilder) {
    this.formBuilder();
  }

  private formBuilder() {
    debugger;
    this.contactForm = this.fb.group({
      name: ['',Validators.required],
      email: ['',[Validators.email,Validators.required]],
      password: ['', [
        Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[a-zA-Z\d!@#$%^&*]{6,}$/), // Updated pattern
        Validators.minLength(6),
        Validators.required
      ]],
      message: ['',Validators.required]
    });
  }

  onSubmit() {
    debugger;
    if (this.contactForm.valid) {
      console.log(this.contactForm.value); // You can send this data to your backend or perform other actions
      this.contactForm.reset(); // Optional: Reset the form after submission
    } else {
      // Mark all form fields as touched to display validation errors
      this.markFormGroupTouched(this.contactForm);
    }
  }

  markFormGroupTouched(formGroup: FormGroup) {
    debugger;
    Object.values(formGroup.controls).forEach(control => {
      control.markAsTouched();
      if (control instanceof FormGroup) {
        this.markFormGroupTouched(control);
      }
    });
  }
}


Bind the form to the template
<div class="container">
  <div class="card mt-4">
    <div class="card-body">
      <form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
        <div class="mb-3">
          <label for="name" class="form-label">Name:</label>
          <input type="text" id="name" class="form-control" formControlName="name">
          <div *ngIf="contactForm.get('name')?.errors && contactForm.get('name')?.touched" class="invalid-feedback">
            <div *ngIf="contactForm.get('name')?.hasError('required')">Name is required.</div>
          </div>
        </div>
        <div class="mb-3">
          <label for="email" class="form-label">Email:</label>
          <input type="email" id="email" class="form-control" formControlName="email">
          <div *ngIf="contactForm.get('email')?.errors && contactForm.get('email')?.touched" class="invalid-feedback">
            <div *ngIf="contactForm.get('email')?.hasError('required')">Email is required.</div>
            <div *ngIf="contactForm.get('email')?.hasError('email')">Invalid email format.</div>
          </div>
        </div>
        <div class="mb-3">
          <label for="password" class="form-label">Password:</label>
          <input type="password" id="password" class="form-control" formControlName="password">
          <div *ngIf="contactForm.get('password')?.errors && contactForm.get('password')?.touched" class="invalid-feedback">
            <div *ngIf="contactForm.get('password')?.hasError('required')">Password is required.</div>
            <div *ngIf="contactForm.get('password')?.hasError('minlength')">Password must be at least 6 characters long.</div>
            <div *ngIf="contactForm.get('password')?.hasError('pattern')">Password must contain at least one uppercase letter, one lowercase letter, and one digit and special character.</div>
          </div>
        </div>
        <div class="mb-3">
          <label for="message" class="form-label">Message:</label>
          <textarea id="message" class="form-control" formControlName="message"></textarea>
          <div *ngIf="contactForm.get('message')?.errors && contactForm.get('message')?.touched" class="invalid-feedback">
            <div *ngIf="contactForm.get('message')?.hasError('required')">Message is required.</div>
          </div>
        </div>
        <button type="submit" class="btn btn-primary" [disabled]="contactForm.invalid">Submit</button>
      </form>
    </div>
  </div>
</div>


Implement form submission logic in the component class
onSubmit() {
    debugger;
    if (this.contactForm.valid) {
      console.log(this.contactForm.value); // You can send this data to your backend or perform other actions
      this.contactForm.reset(); // Optional: Reset the form after submission
    } else {
      // Mark all form fields as touched to display validation errors
      this.markFormGroupTouched(this.contactForm);
    }
  }

Working with Reactive Forms
Once the form is created, you can interact with it programmatically to access form controls, validate form inputs, and react to changes. Here are some common tasks when working with reactive forms:
const name = this.contactForm.get('name');

Add the Validators
private formBuilder() {
    debugger;
    this.contactForm = this.fb.group({
      name: ['',Validators.required],
      email: ['',[Validators.email,Validators.required]],
      password: ['', [
        Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[a-zA-Z\d!@#$%^&*]{6,}$/), // Updated pattern
        Validators.minLength(6),
        Validators.required
      ]],
      message: ['',Validators.required]
    });
  }


Reacting to Form Changes

You can subscribe to value changes or status changes of the form or individual form controls to react to changes in the form:

this.contactForm.valueChanges.subscribe(value => {
  console.log('Form value changed:', value);
});




AngularJS Hosting Europe - HostForLIFE.eu :: Including Web.config While Taking Build in Angular 15 or Less

clock February 28, 2024 06:05 by author Peter

To include the Web.config file in the dest folder while running a build in Angular, you can modify the angular.json file as follows:


Angular.Json
Note: We need to include Web.config file inside the src folder.)

In build declaration, we can define the web config inside the block of assets.
"build": {
       "builder": "@angular-devkit/build-angular:browser",
       "options": {
         "outputPath": "dist",
         "index": "src/index.html",
         "main": "src/main.ts",
         "polyfills": "src/polyfills.ts",
         "tsConfig": "tsconfig.app.json",
         "inlineStyleLanguage": "scss",
         "assets": [
           "src/favicon.ico",
           "src/assets",
           "src/web.config"
         ],
         "styles": [
           "src/styles.scss"
         ],
         "scripts": [
           "node_modules/jquery/dist/jquery.min.js"
         ]
       }

     },

Another Way

In build declaration inside the asset block we can define the we.config with input and output.
{
"assests":{
"src/web.config",
              {
                "glob": "**/*",
                "input": "node_modules/ng2-pdfjs-viewer/pdfjs",
                "output": "assets/pdfjs"
              },
...
...
...
}
}



AngularJS Hosting Europe - HostForLIFE.eu :: Show/Hide Div on Click of Radio Button using Angular and Bootstrap

clock February 19, 2024 06:58 by author Peter

This article will teach us how to use the ngModel directive in the Angular application to show and hide div when the radio button is clicked. Additionally, we study how to construct the Bootstrap Toasts component in Angular. The process of creating the radio buttons, binding the div to radio buttons, and hiding and showing after selection is template-driven.


Note: As stated below, please read my prior essay on Angular applications before beginning this session.

1. In the App Module, import the FormsModule
To work with angular forms, import the forms module (FormsModule) and add the imports: [] array section. Look for the code below in the file src/app/app.module.ts.

import { BrowserModule, Title } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [Title],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 2: Modify the HTML template

The radio buttons are defined here, along with the ngModel directive and the value it receives. The checked state and values are defined in a similar manner. Initially concealed, four divisions become visible when clicking the radio button. Look for the code in the file src/app/app.component.html.

<div class="card bg-warning text-white">
<div class="card-body">
  <h2>Angular Radio Button Click For Show or Hide Div</h2>
    <input [value]="1" [(ngModel)]="sh" name="sh" type="radio" [checked]="isChecked" /> Peter
  &nbsp;
    <input [value]="0" [(ngModel)]="sh" name="sh" type="radio" [checked]="!isChecked" /> Scott
  <div class="text-center card bg-success text-white" *ngIf="sh == 1">Satyaprakash</div>
  <div class="text-center card bg-danger text-white" *ngIf="sh == 0">Kulu</div>
</div>
</div>

<div class="toast show" style="position: absolute; top: 0; right: 0; color: red;font-weight:900;font-size:larger;" *ngIf="sh == 1">
  <div class="toast-header">
    You Selected
    <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
  </div>
  <div class="toast-body">
    Peter
  </div>
</div>

<div class="toast show" style="position: absolute; top: 0; right: 0;color: red;font-weight:900;font-size:larger;" *ngIf="sh == 0">
  <div class="toast-header">
    You Selected
    <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
  </div>
  <div class="toast-body">
    Kulu
  </div>
</div>

Radio buttons are used in this implementation of the ngModel directive.
<input [value]="1" [(ngModel)]="sh" name="sh" type="radio" [checked]="isChecked" /> Peter
  &nbsp;
<input [value]="0" [(ngModel)]="sh" name="sh" type="radio" [checked]="!isChecked" /> Scott

For normal Div show or hide,
<div class="text-center card bg-success text-white" *ngIf="sh == 1">Peter</div>
<div class="text-center card bg-danger text-white" *ngIf="sh == 0">Scott</div>


For Bootstrap Toast component,
<div class="toast show" style="position: absolute; top: 0; right: 0; color: red;font-weight:900;font-size:larger;" *ngIf="sh == 1">
  <div class="toast-header">
    You Selected
    <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
  </div>
  <div class="toast-body">
    Peter
  </div>
</div>

<div class="toast show" style="position: absolute; top: 0; right: 0;color: red;font-weight:900;font-size:larger;" *ngIf="sh == 0">
  <div class="toast-header">
    You Selected
    <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
  </div>
  <div class="toast-body">
    Scott
  </div>
</div>

Step 3. Update TypeScript Template
Here we set the isChecked variable with false value. Make sure to define another variable by the name of “sh” in angular TypeScript component. Add the code in src/app/app.component.ts file.
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  isChecked: boolean = false;
  sh: any;
  constructor() {
  }
}


Step 4. Add Bootstrap to make page responsive
Add code in index.html file,
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Title Service Example</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
  <app-root></app-root>
</body>
</html>


Output
Here, we run the command (ng serve) to start the angular app server.  The result is shown on first time page load:

Then it performs hide and show HTML div on radio buttons click in angular application with the help of ngModel directive.



AngularJS Hosting Europe - HostForLIFE.eu :: Angular Content Projection: Reusability and Flexibility of the UI

clock February 1, 2024 08:13 by author Peter

The robust front-end framework Angular offers developers a number of tools to create dynamic and manageable user interfaces. Content projection is one such feature that greatly enhances UI flexibility and reusability. Through the dynamic injection of content into predetermined slots inside a component's template, content projection enables developers to design components that are both adaptable and reusable.


Comprehending Content Projection

A feature in Angular called content projection, or transclusion, allows content from a parent component to be inserted into a specific area of a child component. This method facilitates the creation of adaptable and adjustable user interfaces and encourages component reuse.

Content Projection's Advantages
Component Reusability: Content projection enables programmers to design components that may be applied to various areas of an application at different times. Content can be projected into designated slots to increase component versatility and adaptability to a range of use scenarios.
Simplified API: Rather than requiring intricate setups, components may expose a simplified API that accepts content as input. This improves code maintainability by making the components simpler for developers to use and comprehend.
Consistent Style and Layout: Content projection aids in preserving uniform styling and layout throughout an application's many sections. Components with specified slots can be designed by developers to guarantee that the content projection follows a consistent format.
Improved Concern Separation: Content projection promotes a distinct division of responsibilities between the parent and child components. Child components manage the content display, allowing parents to concentrate on business logic, thus fostering a modular and maintainable codebase.

Practical Use Case
Think of a basic card component that can show text, photos, or even bespoke components, among other kinds of information. We may construct a reusable card component that can adjust to various content kinds by using content projection.

card.component.ts

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

@Component({
  selector: 'app-card',
  standalone: true,
  imports: [],
  template: `
    <div class="card">
      <div class="card-header">
        <ng-content select="[card-header]"></ng-content>
      </div>
      <div class="card-body">
        <ng-content select="[card-body]"></ng-content>
      </div>
      <div class="card-footer">
        <ng-content select="[card-footer]"></ng-content>
      </div>
    </div>
  `,
  styles: [
    '.card { border: 1px solid #ddd; border-radius: 8px; overflow: hidden; margin: 16px; }',
    '.card-header, .card-footer { background-color: #f0f0f0; padding: 8px; }',
    '.card-body { padding: 16px; }',
  ],
})
export class CardComponent {}


In this example, the CardComponent defines three slots: card-header, card-body, and card-footer. The content projected into these slots will be rendered within the corresponding sections of the card.

app.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { CardComponent } from './card/card.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, CardComponent],
  template: `
    <app-card>
      <div card-header>
        <h2>Angular is awesome</h2>
      </div>
      <div card-body>
        <p>Lets have a fun with it</p>
      </div>
      <div card-footer>
        <button>Read More</button>
      </div>
    </app-card>

    <app-card>
      <div card-header>
        <h2>Product Information</h2>
      </div>
      <div card-body>
        <img
          src="https://cdn-images-1.medium.com/v2/resize:fit:184/1*[email protected]"
          alt="Product Image"
          style="max-width: 100%"
        />
        <ul>
          <li>Feature 1</li>
          <li>Feature 2</li>
          <li>Feature 3</li>
        </ul>
      </div>
      <div card-footer>
        <button>Add to Cart</button>
      </div>
    </app-card>
  `,
})
export class AppComponent {}



AngularJS Hosting Europe - HostForLIFE.eu :: Optimizing Templates for Angular

clock January 19, 2024 09:28 by author Peter

Immutable Objects: When using OnPush, it's beneficial to work with immutable objects. If you need to modify data, create a new object or array instead of modifying the existing one. This helps Angular recognize changes more efficiently.
this.data = [...this.data, newElement]; // Using the spread operator for arrays

Input Properties: Ensure that your component's input properties are used correctly. When an input property changes, Angular triggers change detection for components using the OnPush strategy. If you're working with complex data structures, consider using @Input setters to handle changes.
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-item',
  templateUrl: 'item.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ItemComponent {
  private _data: any;

  @Input()
  set data(value: any) {
    this._data = value;
    // handle changes if needed
  }

  get data(): any {
    return this._data;
  }
}


Event Handling: Be cautious with event handling. When using OnPush, events outside of Angular's knowledge (e.g., events from third-party libraries) may not trigger change detection automatically. Use ChangeDetectorRef to manually mark the component for check.
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: 'example.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
  constructor(private cdr: ChangeDetectorRef) {}

  // Trigger change detection manually
  handleExternalEvent() {
    this.cdr.markForCheck();
  }
}


By using the OnPush change detection strategy and following these best practices, you can make your Angular application more efficient and responsive, especially in scenarios where components have a limited set of inputs or depend on immutable data.

2. Limit ngIf and ngFor in the Template

Limiting the use of ngIf and ngFor directives in your Angular templates is crucial for optimizing performance, as excessive use can lead to unnecessary rendering and affect the efficiency of change detection. Here are some best practices to follow:

  • Minimize ngIf and ngFor Nesting: Avoid deep nesting of ngIf and ngFor directives within your templates. The deeper the nesting, the more complex the change detection process becomes. Try to flatten your template structure when possible.
  • Filter Data Before Rendering: Instead of using ngFor to loop through all items and then applying conditions using ngIf, consider filtering your data in the component before rendering. This can reduce the number of elements in the template and improve rendering performance.

    <!-- Avoid -->
    <div *ngFor="let item of items" *ngIf="item.isValid">
      <!-- content -->
    </div>

    <!-- Prefer -->
    <div *ngFor="let item of validItems">
      <!-- content -->
    </div>


Use TrackBy with ngFor: When using ngFor, always provide a trackBy function to help Angular identify which items have changed. This can significantly improve the performance of rendering lists.
    <div *ngFor="let item of items; trackBy: trackByFn">
      <!-- content -->
    </div>


trackByFn(index, item) {
  return item.id; // Use a unique identifier
}


Avoid Excessive Use of Structural Directives: Be mindful of using too many structural directives (ngIf, ngFor, etc.) within a single template. Each structural directive introduces a potential change detection cycle, and having many of them can impact performance.

Lazy Load Components with ngIf: If you have complex or resource-intensive components, consider lazy-loading them using the ngIf directive. This way, the components will only be instantiated when they are needed.
<ng-container *ngIf="showComponent">
  <app-lazy-loaded-component></app-lazy-loaded-component>
</ng-container>


  • Paginate Large Lists: If dealing with large datasets, consider implementing pagination or virtual scrolling to load and render only the visible portion of the data. This can significantly improve the initial rendering time.
  • Profile and Optimize: Use Angular's built-in tools like Augury or browser developer tools to profile your application's performance. Identify components with heavy rendering and optimize accordingly.

3.  Lazy Loading Images
Lazy loading images is a technique that defers the loading of non-critical images until they are about to be displayed on the user's screen. This can significantly improve the initial page load time, especially for pages with a large number of images. Angular provides several ways to implement lazy loading of images. Here's a common approach:

Native Lazy Loading (HTML loading attribute): The HTML standard has introduced a loading attribute for the <img> element, which allows you to set the loading behavior of an image. The values can be "eager" (default), "lazy", or "auto". Setting it to "lazy" will enable lazy loading.
    <img src="image.jpg" alt="Description" loading="lazy">

The browser will then decide when to load the image based on its visibility in the viewport.

Angular Directives for Lazy Loading: You can use Angular directives for more control over lazy loading, especially if you need to perform custom actions when an image is loaded or when it enters the viewport.

a. Intersection Observer: Use the Intersection Observer API to detect when an element (such as an image) enters the viewport. Angular provides a directive named ng-lazyload-image that simplifies the integration with Intersection Observer.
npm install ng-lazyload-image

import { NgModule } from '@angular/core';
import { LazyLoadImageModule } from 'ng-lazyload-image';

@NgModule({
  imports: [LazyLoadImageModule],
  // ...
})
export class YourModule { }


<img [defaultImage]="'loading.gif'" [lazyLoad]="imagePath" alt="Description">

b. Custom Lazy Loading Directive: Alternatively, you can create a custom directive for lazy loading images. This approach provides more flexibility but requires a bit more code. You can use the Intersection Observer API or a library like lozad.js.
// lazy-load.directive.ts
import { Directive, ElementRef, Renderer2, OnInit } from '@angular/core';

@Directive({
  selector: '[appLazyLoad]'
})
export class LazyLoadDirective implements OnInit {

  constructor(private el: ElementRef, private renderer: Renderer2) { }

  ngOnInit() {
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.loadImage();
          observer.unobserve(entry.target);
        }
      });
    });

    observer.observe(this.el.nativeElement);
  }

  private loadImage() {
    const imgSrc = this.el.nativeElement.getAttribute('data-src');
    if (imgSrc) {
      this.renderer.setAttribute(this.el.nativeElement, 'src', imgSrc);
    }
  }
}


<img [appLazyLoad]="imagePath" data-src="loading.gif" alt="Description">

4. ng-container
Use the <ng-container> element to group elements without introducing additional elements to the DOM. It is a lightweight container that doesn't render as an HTML element.
<ng-container *ngIf="condition">
  <!-- content -->
</ng-container>


5. Avoid Heavy Computation in Templates
Keep your templates simple and avoid heavy computations or complex logic. If necessary, perform such operations in the component class before rendering.
Move Logic to the Component
Use Pure Pipes Judiciously
Memoization
NgIf and NgFor Directives

6. Use Angular Pipes Efficiently
Be cautious with Angular pipes, especially those that involve heavy computations. Pipes can have an impact on performance, so use them judiciously. Consider memoization techniques if a pipe's output is deterministic and costly.
// component.ts
export class MyComponent {
  heavyComputationResult: any;

  ngOnInit() {
    // Perform heavy computation here
    this.heavyComputationResult = /* result */;
  }
}


<!-- component.html -->
<div>{{ heavyComputationResult | formatData }}</div>


7. ngZone Awareness

Be aware of NgZone and its impact on change detection. If you're performing operations outside of Angular (e.g., third-party libraries or asynchronous operations), you may need to use NgZone.run to ensure that change detection is triggered appropriately.

8. Production Build
Always build your application for production using AOT compilation. This helps in optimizing and minifying the code for better performance.
ng build --prod

By applying these optimization techniques, you can enhance the performance of your Angular templates and create a more responsive user experience.

Improving the performance of your Angular application requires optimizing Angular templates. To maximize Angular templates, consider the following advice and best practices:

1. Apply Change Detection using OnPush
Implementing Angular's OnPush change detection approach can greatly enhance your application's performance. Angular is instructed by the OnPush strategy to only check for changes when an event within the component is triggered or when the input attributes of the component change. Reduced change detection cycles may arise from this, improving overall performance. This is how OnPush is used:1.

Configure a Change Detection Method: Set ChangeDetectionStrategy as the changeDetection property in your component decorator.OnPush:

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: 'example.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
  // component logic
}



AngularJS Hosting Europe - HostForLIFE.eu :: Minification and Tree Shaking in Angular

clock January 15, 2024 07:26 by author Peter

Minification and tree shaking are two fundamental techniques used in Angular (and other web development frameworks) to streamline and optimize code for best performance. These methods assist in decreasing the size of your application, which is essential for improved user experience and quicker load times. Now let's examine each of these procedures in relation to Angular:

1. First off, what is minification?
Minification is the process of renaming variables to shorter names and eliminating characters from your code that aren't needed, including whitespace and comments. Your code files will download more quickly as a result of this smaller size. Typically, TypeScript is used to write Angular applications, and it is subsequently transpiled to JavaScript. The JavaScript code that results is subjected to the minification process.

This is how to make Angular's minification enabled.

A. Manufacturing Construct
To build your production application, you can use the build command provided by Angular CLI. The Angular CLI automatically applies minification when you build for production.

ng build --prod

This command generates a production-ready bundle with minified and optimized code.

B. The Terser Plugin
The Terser plugin, used for minification in Angular, provides with different configuration options. By including options in your angular.json file, you can alter the minification procedure.

"architect": {
  "build": {
    "options": {
      "optimization": true,
      "outputPath": "dist/my-app",
      "terserOptions": {
        "compress": {
          "pure_funcs": ["console.log"],
          "drop_console": true
        },
        "mangle": true
      }
    }
  }
}

The functions that are pure and can be safely removed are specified using the pure_funcs parameter in the example above. All console statements are eliminated using the drop_console option, and variable names are obscured by setting mangle to true.

C. Compiling Angular AOT (Ahead-of-Time)
There are two compilation modes for Angular applications: Just-In-Time (JIT) and AOT (Ahead-of-Time). For production builds, AOT compilation is recommended since it enables greater tree shaking and optimization. Smaller bundle sizes are the outcome of its compilation of Angular templates and components during the construction process.

In your tsconfig.json file, you can set AOT compilation to run automatically.

"angularCompilerOptions": {
  "fullTemplateTypeCheck": true,
  "strictInjectionParameters": true
}

2. What Is Shaking of Trees?
The practice of removing unused or dead code from your program is called tree shaking. It contributes to reducing the bundle size by removing any unnecessary modules or code.

A. Configuration of the Module
Make sure the arrangement of your Angular modules permits efficient tree shaking. Dependencies and boundaries between modules should be obvious. To make the process of removing useless code easier, stay away from needless inter-module dependencies.

B. Analysis of Static Data
Tree shaking is most effective when combined with static analysis, so stay away from runtime code or dynamic imports that make it difficult for the build tool to identify which portions of the code are being utilized.

C. Mode of Production
Like minification, production builds yield the best results from tree shaking. Tree shaking is enabled automatically by Angular CLI when you execute the production build with the --prod flag.

ng build --prod

2. What Is Shaking of Trees?
The practice of removing unused or dead code from your program is called tree shaking. It contributes to reducing the bundle size by removing any unnecessary modules or code.

A. Configuration of the Module

Make sure the arrangement of your Angular modules permits efficient tree shaking. Dependencies and boundaries between modules should be obvious. To make the process of removing useless code easier, stay away from needless inter-module dependencies.

B. Analysis of Static Data
Tree shaking is most effective when combined with static analysis, so stay away from runtime code or dynamic imports that make it difficult for the build tool to identify which portions of the code are being utilized.


C. Mode of Production
Like minification, production builds yield the best results from tree shaking. Tree shaking is enabled automatically by Angular CLI when you execute the production build with the --prod flag.

ng build --prod

D. Angular Dependency Injection
The dependency injection system in Angular occasionally causes issues with tree shaking. Steer clear of injecting components or services that aren't needed in a certain module. This guarantees that the services that are not utilized are excluded from the final package.

E. Renderer of Angular Ivy
Angular Ivy, the new rendering engine introduced in Angular 9, adds enhancements to tree shaking. Better static analysis capabilities enable more efficient removal of dead code during the build process.

Configuring Webpack (for Advanced Users):
You can alter the webpack configuration that the Angular CLI uses if you require further control over the build process. This creates a webpack.config.js file in your project and involves ejecting the webpack configuration. Utilize this file to adjust code splitting and optimization, among other build process components.

In order to remove the webpack setup:
ng eject

Remember that ejecting is final and that you will be in charge of keeping the webpack settings updated.

In summary

In summary, minification and tree shaking are combined to optimize Angular apps. Achieving optimal performance requires configuring Terser's settings, turning on AOT compilation, properly structuring modules, and being aware of the limitations of tree shaking. Make sure the optimizations don't affect your application's functioning by conducting extensive testing.



AngularJS Hosting Europe - HostForLIFE.eu :: How To Configure AngularJS Environment Variables?

clock January 10, 2024 07:07 by author Peter

Setting environment variables in an AngularJS application happens at the configuration stage; this usually takes place in a separate file containing the configuration data. This is an illustration of how to set environment variables in an AngularJS application:

First Step
To save the environment variables, create a file in the root directory of your application, say config.js.

Step Two
Use the following code to define the environment variables in the file:

"use strict";
 angular.module('config', [])
.constant('ENV', {name:'development',tokenURL:'http://localhost:62511/token',apiURL:'http://localhost:62511/api',biUrl:'http://localhost:4200/',backgroundimage:'../images/backgroundimage.jpg',logo:'images/ogo.png'});


Step 3

Include the config.js file in your HTML file, just like any other JavaScript file:
<script src="scripts/index.config.js"></script>

Step 4

Inject the env constant in your AngularJS controllers, services, or directives to access the environment variables,

angular.module("myApp").controller("MyController", function($scope, env) {
    console.log(env.apiUrl);
    console.log(env.debugEnabled);
});
development: {
        options: {
            dest: '<%= yeoman.app %>/scripts/config.js'
        },
        constants: {
            ENV: {
                name: 'development',
                tokenURL: "http://localhost:62511/token",
                apiURL: "http://localhost:62511/api",
                biUrl: "http://localhost:4200/",
                backgroundimage: "../images/backgroundimage.jpg",
                logo: "images/logo.png",
            }
        }
    },
    qa: {
        options: {
            dest: '<%= yeoman.dist %>/scripts/config.js'
        },
        constants: {
            ENV: {
                name: 'qa',
                tokenURL: "https://qa.hostforlife.eu/token",
                apiURL: "https://qa.
hostforlife.eu/api",
                biUrl: "https://qa-dashboard.
hostforlife.eut/",
                backgroundimage: "../images/backgroundimage.jpg",
                logo: "images/logo.png",
            }
        }
    },

Grunt command to run the Application,

grunt build --qa



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in