Full Trust European Hosting

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

AngularJS Hosting Europe - HostForLIFE.eu :: The Distinction Between Vue, React, and Angular.js

clock May 22, 2024 08:11 by author Peter

Three front-end frameworks have become well-known in the constantly changing field of web development: Angular, React, and Vue.js. These technologies each address contemporary coding difficulties in a different way, and each has special strengths and use cases. This blog examines their development, history, and salient characteristics to assist you in selecting the best one for your upcoming undertaking.

Angular The all-encompassing structure
Evolution and History

Angular's Model-View-Controller (MVC) architecture and two-way data binding transformed front-end development when it was first released by Google in 2010 under the name AngularJS. A comprehensive overhaul of AngularJS, Google launched Angular (also known as Angular 2+) in 2016 to solve the shortcomings of the original framework and meet the demands of contemporary web development.

Key Features

  • TypeScript: Angular is built using TypeScript, a statically typed superset of JavaScript, enhancing code quality and maintainability.
  • Comprehensive Toolset: Angular offers a full-fledged framework with tools and libraries for routing, form handling, HTTP client, and more.
  • Two-way Data Binding: Simplifies the synchronization between the model and the view, making development more intuitive.
  • Dependency Injection: Enhances modularity and reusability of components by injecting dependencies where needed.


Use Cases
Angular is ideal for large-scale enterprise applications where a robust, scalable, and maintainable solution is required. Its comprehensive nature allows for the development of complex, feature-rich applications.

React The flexible library

History and Evolution
React was developed by Facebook and released in 2013. Unlike Angular, React is a library focused on building user interfaces, particularly single-page applications. It introduced the concept of a virtual DOM and component-based architecture, which significantly improved performance and developer productivity.

Key Features

  • Virtual DOM: React’s virtual DOM improves performance by minimizing direct manipulations of the real DOM.
  • Component-Based Architecture: Promotes reusable, self-contained components, making the development process modular and manageable.
  • JSX Syntax: Allows developers to write HTML-like code within JavaScript, streamlining the creation of UI components.
  • Unidirectional Data Flow: Simplifies data management and debugging by ensuring data flows in a single direction through the application.


Use Cases
React is suited for dynamic and high-performing applications, such as social media platforms, e-commerce sites, and content management systems. Its flexibility and performance benefits make it a popular choice among developers.

Vue.js The progressive framework

History and Evolution
Vue.js was created by Evan You and released in 2014. It was designed to be an approachable and versatile framework, combining the best features of Angular and React while offering a gentle learning curve. Vue has grown rapidly in popularity due to its simplicity and powerful features.

Key Features

  • Reactive Data Binding: Simplifies the connection between the model and the view, making development intuitive.
  • Component-Based Architecture: Encourages the use of reusable, modular components.
  • Single-File Components: Allows developers to encapsulate HTML, CSS, and JavaScript within a single file, promoting better organization and maintainability.
  • Flexibility: Vue can function as a library for enhancing existing projects or as a full-fledged framework for new applications.


Use Cases
Vue.js is perfect for both small and large-scale applications. Its progressive nature allows developers to incrementally adopt its features, making it a flexible choice for projects of varying complexity.

Angular vs React vs Vue.js

Feature Angular React Vue.js
Initial Release 2010 (AngularJS), 2016 (Angular) 2013 2014
Developed By Google Facebook Evan You (Open Source)
Language TypeScript JavaScript (JSX) JavaScript
Architecture MVC, Component-based Component-based Component-based
Data Binding Two-way One-way Two-way
Performance Good Excellent Excellent
Learning Curve Steep Moderate Gentle
Use Case Large enterprise applications Dynamic, high-performing apps Flexible, any size applications

 



AngularJS Hosting Europe - HostForLIFE.eu :: startWith() Operator in Angular

clock May 15, 2024 08:44 by author Peter

The RxJS library's Angular module's startWith() operator is used to prepend a starting value or set of values to the start of an observable series. This operator makes sure that these initial values are released as soon as the observable is subscribed, before it starts to release its typical series of values.


Setting up

Make sure your Angular project has RxJS installed. If it's not installed already, npm can be used to add it:

Usage
Import the startWith operator from RxJS in the component or service where you want to use it:
import { startWith } from 'rxjs/operators';

Example
Let's illustrate how startWith() works with a practical example.

Service Definition

Assume you have a service that provides an observable stream of numbers:
import { Injectable } from '@angular/core';
import { Observable, interval } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NumberService {

  getNumbers(): Observable<number> {
    return interval(1000); // Emits incremental numbers every second
  }
}


Component Implementation

In your component, you can consume this service and use the startWith() operator to prepend an initial value before the stream of numbers starts emitting.
import { Component, OnInit } from '@angular/core';
import { NumberService } from './number.service';
import { startWith } from 'rxjs/operators';

@Component({
  selector: 'app-number-display',
  template: `
    <h2>Number Stream</h2>
    <ul>
      <li *ngFor="let number of numberStream$ | async">{{ number }}</li>
    </ul>
  `
})
export class NumberDisplayComponent implements OnInit {

  numberStream$: Observable<number>;

  constructor(private numberService: NumberService) { }

  ngOnInit(): void {
    this.numberStream$ = this.numberService.getNumbers().pipe(
      startWith(0) // Prepend 0 as the initial value
    );
  }

}


In this example

  • this.numberService.getNumbers() returns an observable that emits incremental numbers every second using interval(1000).
  • startWith(0) is used within the pipe() method to prepend the initial value 0 to the beginning of the observable sequence. This means that 0 will be emitted immediately upon subscription, before the interval starts emitting numbers.

Template Usage
In the component's template (number-display.component.html), subscribe to numberStream$ using the async pipe to display the emitted numbers:
<h2>Number Stream</h2>
<ul>
  <li *ngFor="let number of numberStream$ | async">{{ number }}</li>
</ul>




AngularJS Hosting Europe - HostForLIFE.eu :: How to Install an Angular 17 Application Without Cost?

clock May 7, 2024 07:17 by author Peter

Google offers the Firebase Console for free hosting of your Angular application. With Firebase, you can create and expand popular apps and games that users like. endorsed by Google and relied upon by millions of companies worldwide.

Login to firebase with your google account.
https://firebase.google.com

Create Angular 17 Application using Angular CLI

As of today (May 5th, 2024) Angular 17.3.6 is the latest version.
We can upgrade our Angular CLI to latest version.

C:\Users\peter>npm install @angular/cli -g

We can upgrade the npm also
npm install -g [email protected]

We can check the Angular CLI version now.

We can create an Angular application now.
D:\Work\Angular\001>ng new AngularGlobe

After installing the packaging, we can go to the application in Visual Studio Code by Microsoft.

We can run the angular application by below command.
ng serve

We can add our globe image in app.component.html file with a small style class in app.component.css as well.

app.component.html

<h1>
  <img src="../assets/Our_Moon_Phases_and_Eclipses.gif" class="center">
</h1>
<p class="center">

  <a href="https://www.esa.int/" target="_blank">Image Courtesy : THE EUROPEAN SPACE AGENCY</a>
</p>

app.component.css
.center {
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 50%;
  }

Login Firebase Console with Google account.
We can give a name to our Angular project.

Configure google analytics.

Various options available in Firebase. You can explore each feature.

We can focus on Hosting options.

We have to install firebase-tools
npm install -g firebase-tools
firebase login


Proceed Yes

You can select the hosting option with space bar.
We have already created a project in Firebase.
Please select the project with existing project option.

Now we must select the build folder.

Before selecting the build folder we can build our project using below command.

ng build

Now we have choose the build folder.

NB: The deployment path has been modified by the Angular team to dist\<project name>\browser.

This allows us to deploy the application at this time.

Firebase Deploy

Application is deployed to https://angular-globe.web.app

If needed, you can purchase a domain from GoDaddy or BlueHost and link with Firebase free domain.



AngularJS Hosting Europe - HostForLIFE.eu :: Angular v16: Data Exchange Between Parent & Child Components

clock April 30, 2024 10:36 by author Peter

In Angular development, effective communication between parent and child components is essential for creating dynamic and interactive apps. We will explore two essential data exchange techniques in this extensive guide: sending data from a parent component to a child component and receiving data in return from a child component to a parent component. Join us as we thoroughly examine each technique, offering concise explanations and helpful code samples all along the way.

Data Transmission from Parent to Child:
Step 1: In the parent component, define the data Define the data that will be sent to the child component in the parent component (Parent.component.ts).

export class ParentComponent
{
  data: string = 'This is data from the parent component';
}

Explanation. Here, we define a variable data in the parent component to hold the information that will be sent to the child component.

Step 2. Pass Data to Child Component In the parent component template (Parent.component.html), use property binding to pass the data to the child component.
<app-child [childData]="data"></app-child>

Explanation. We use property binding to bind the data variable from the parent component to the childData input property of the child component.

Step 3. Receive Data in Child Component In the child component (Child.component.ts), use the @Input decorator to receive the data from the parent component.
export class ChildComponent
{
  @Input() childData: string | undefined | any;
}

Explanation. Here, we use the @Input decorator to define an input property childData, which will receive the data passed from the parent component.

Step 4. Display Data in Child Component In the child component template (header.component.html), display the received data.
<p>{{childData}}</p>

Explanation. We simply display the childData received from the parent component within the child component's template.

Sending Data from Child to Parent Component:
Step 1. Define Event in Child Component In the child component (Child.component.ts), define an event emitter to send data to the parent component.
export class ChildComponent
{
  data: string = 'This is data from the child component';
  @Output() dataSent = new EventEmitter<string>();

  sendDataToParent(): void
  {
    this.dataSent.emit(this.data);
  }
}


Explanation. Here, we define an event emitter, dataSent, which emits data of type string. We also create a method sendDataToParent() to emit the data when called.

Step 2. Receive Data in Parent Component In the parent component (Parent.component.ts), define a method to receive the data from the child component.
export class ParentComponent
{
  receivedData: string | undefined;

  onDataReceived(data: string): void
  {
    this.receivedData = data;
  }
}

Explanation. We define a method onDataReceived() in the parent component to handle the data received from the child component.

Step 3. Handle Data Event in Parent Component Template In the parent component template (Parent.component.html), bind to the data event emitted by the child component and handle it using the method defined in Step 2.
<app-child (dataSent)="onDataReceived($event)"></app-child>

Explanation. Here, we bind to the dataSent event emitted by the child component and call the onDataReceived() method in the parent component, passing the received data as an argument.

Conclusion

By meticulously following these step-by-step instructions, you can seamlessly achieve data exchange between parent and child components in Angular v16. Whether transmitting data from a parent component to a child component or vice versa, these techniques empower you to craft immersive and interactive user experiences within your Angular applications. Unlock the full potential of Angular v16 and elevate your development prowess with these essential data communication methods.



Node.js Hosting Europe - HostForLIFE.eu :: How to Create a Node.js Logging System with Express?

clock April 25, 2024 13:50 by author Peter

In contemporary web development, logging plays a crucial role in program monitoring and troubleshooting. Node.js offers a variety of logging tools for monitoring and analyzing application operations because of its event-driven architecture. This article will walk through how to build a logging system for a Node.js application using Winston, a versatile logging package, and Express, a popular web framework.

What is Logging?
The process of keeping track of activities and occurrences inside a software system is called logging. These log entries help with debugging, monitoring, auditing, and security. They include timestamps, severity levels, messages, and contextual data. Logging helps with performance analysis, intrusion detection, compliance adherence, and troubleshooting by capturing important information about system behavior. With their ability to provide insights into application flow, performance bottlenecks, user actions, and security concerns, logs are an indispensable tool for developers, administrators, and security professionals. Logging is essentially a basic procedure used in software development and operations that makes software systems easier to manage, secure, and monitor.

Why we use Logging?

Logging serves several essential purposes in software development:

  • Debugging and Troubleshooting: Logs are an important source of information for troubleshooting and identifying difficulties with a program. To comprehend the execution flow, spot faults, and find the source of problems, developers can go through log messages.
  • Monitoring and Performance Optimization: Developers may keep an eye on an application's performance in real time with the help of logs. Developers can pinpoint performance bottlenecks, maximize resource use, and raise the application's general effectiveness by examining log data.
  • Auditing and Compliance: Keeping track of user actions and system events is facilitated by logging. For compliance with legal standards like GDPR, HIPAA, or PCI DSS, this audit trail is crucial. Logs are useful for monitoring user behavior, spotting illegal access, and guaranteeing the accuracy of data.
  • Security and Intrusion Detection: When it comes to identifying security risks and unauthorized access attempts, logs are essential. Events including unsuccessful login attempts, questionable activity, and possible security breaches are recorded in security logs. Administrators are able to quickly identify and address security incidents by examining security logs.

Steps for Creating a Project
Step 1.  Setting Up the Project
Use my previous article for setting up Node.js, "How to upload file in Node.js" In this article, we mentioned important commands for uploading files in Node.js.

Step 2. Integrating Winston for Logging

Winston is a versatile Node.js logging package that supports many transports, such as file, database, and terminal. Winston will be set up to log messages to both the console and a log file at various levels (info, error, etc.).
// main.js

const winston = require('winston');

// Create a logger instance
const logger = winston.createLogger({
  level: 'info', // Logging level
  format: winston.format.json(), // Log format
  transports: [
    // Log to the console
    new winston.transports.Console(),
    // Log to a file
    new winston.transports.File({ filename: 'logging_file.log' })
  ]
});


Step 3.  Implementing Logging Middleware in Express
We are able to intercept and handle incoming requests thanks to express middleware. A unique middleware function will be developed to log incoming HTTP requests. Request methods, URLs, and other pertinent data will be recorded by this middleware and logged using Winston.
// Middleware to log requests
app.use((req, res, next) => {
  logger.log('info', `${req.method} ${req.url}`);
  next();
});

Step 4.  Creating Routes and Handling Errors
After installing logging middleware, we will create our Express application's routes. To show how to handle requests, we'll construct a simple route for the main page ("/"). Furthermore, error handling middleware will be implemented to log and manage any faults that arise during request processing.
// Route handling
app.get('/', (req, res) => {
  res.send('Hello, world!');
});

// Error handling middleware
app.use((err, req, res, next) => {
  logger.log('error', err.stack);
  res.status(500).send('Something broke!');
});


Step 5. Serving Log File via Web Interface
We'll develop an additional route ("/logs") that reads the contents of the log file and sends it to the client in order to give a user-friendly way for log files to be viewed. In order to ensure security and avoid dangerous infinite loops, this route will ignore logging requests so they are not kept in the log file.
// Route to serve log file
app.get('/logs', (req, res) => {
  fs.readFile('combined.log', 'utf8', (err, data) => {
    if (err) {
      logger.log('error', err);
      return res.status(500).send('Error reading log file');
    }
    res.type('text/plain').send(data);
  });
});


Step 6. Running the Application

Finally, let us launch our Express application and verify its operation. To start the HTTP request logging, start the server and visit the home page. You may also view the contents of the log file using the web interface by going to the "/logs" route.
node main.js

Output



AngularJS Hosting Europe - HostForLIFE.eu :: Methods for Data Transfer in Angular

clock April 18, 2024 08:36 by author Peter

As a potent framework for creating dynamic and interactive single-page applications (SPAs), Angular has made a name for itself. An important problem for developers working with Angular apps is effectively and efficiently moving data across components. Fortunately, Angular offers a number of techniques, each designed to fit a particular use case or scenario, to help with this data transmission process. We'll examine the many Angular methods of data transfer across components in this article.

1. Bindings for Input and Output
Angular components can employ input and output bindings to exchange data with one another. While output bindings allow child components to broadcast events back to their parent components, input bindings let a parent component to pass data to its child components.

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

@Component({
  selector: 'app-parent',
  template: `
    <app-child [inputData]="parentData" (outputEvent)="handleOutput($event)"></app-child>
  `
})
export class ParentComponent {
  parentData = 'Data from parent';

  handleOutput(data: any) {
    // Handle emitted data from child component
  }
}

// Child Component
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    <p>{{ inputData }}</p>
    <button (click)="emitData()">Emit Data</button>
  `
})
export class ChildComponent {
  @Input() inputData: any;
  @Output() outputEvent = new EventEmitter<any>();

  emitData() {
    this.outputEvent.emit('Data from child');
  }
}


2. Services

Angular services act as singletons that can be injected into any component throughout the application. They are ideal for sharing data and functionality across multiple components.
// Shared Service
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private dataSubject = new BehaviorSubject<any>(null);
  data$ = this.dataSubject.asObservable();

  setData(data: any) {
    this.dataSubject.next(data);
  }
}

// Components
import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-sender',
  template: `
    <button (click)="sendData()">Send Data</button>
  `
})
export class SenderComponent {
  constructor(private dataService: DataService) {}

  sendData() {
    this.dataService.setData('Data from sender');
  }
}

@Component({
  selector: 'app-receiver',
  template: `
    <p>{{ receivedData }}</p>
  `
})
export class ReceiverComponent {
  receivedData: any;

  constructor(private dataService: DataService) {
    this.dataService.data$.subscribe(data => {
      this.receivedData = data;
    });
  }
}


3. Route Parameters and Query Parameters
// Routing Module
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Component1Component } from './component1.component';
import { Component2Component } from './component2.component';

const routes: Routes = [
  { path: 'component1/:id', component: Component1Component },
  { path: 'component2', component: Component2Component }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

// Components
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-component1',
  template: `
    <p>{{ id }}</p>
  `
})
export class Component1Component implements OnInit {
  id: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.id = params['id'];
    });
  }
}

@Component({
  selector: 'app-component2',
  template: `
    <a [routerLink]="['/component1', '123']">Go to Component 1 with ID</a>
  `
})
export class Component2Component { }


Data communication between components is essential to creating scalable and reliable solutions in Angular apps. Through the utilization of methods like services, routing systems, and input and output bindings, developers may proficiently oversee data flow and communication in their applications. Gaining knowledge of these Angular data transfer methods enables developers to create Angular apps that are more modular, efficient, and manageable.



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);
});




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