Full Trust European Hosting

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

AngularJS Hosting Europe - HostForLIFE.eu :: Using Pipes to Create Clear and Effective Angular Applications

clock January 8, 2025 06:45 by author Peter

The use of "pipes" is one of Angular's most potent tools for formatting and changing data inside templates. Developers can apply transformations like formatting dates, changing text cases, or even filtering data in an efficient and reusable way by using pipes, which offer a declarative mechanism to handle data before it is shown to the user.

Writing clean, manageable, and modular code for Angular applications requires an understanding of pipes. The main distinctions between pipes and functions will be discussed in this post, along with how to use built-in pipes and make your own custom pipes to increase Angular's functionality. You will have a firm grasp on how to integrate pipes into your Angular projects to improve user experience and expedite data presentation by the end of this tutorial.

What is an Angular Pipe?
In Angular, a pipe is a way to transform data before it is displayed in the user interface. Pipes can be used in templates to modify or format data without having to alter the original data.

Pipes are an Angular concept, not a TypeScript (TS) feature. They are a core part of Angular’s template syntax and are used to transform data in the view (template) layer of Angular applications.

Key Points about Pipes in Angular

  • Angular-Specific: Pipes are a built-in feature of the Angular framework designed to be used in Angular templates. They are not a native feature of JavaScript or TypeScript.
  • Purpose: Their primary function is to transform data in the template before it is displayed to the user. This transformation can include formatting dates, numbers, currencies, filtering arrays, or performing more complex data transformations.

Declarative Transformation: Pipes enable declarative transformation of data within the template, meaning that the logic for transforming data is cleanly abstracted away from the component’s TypeScript code.

You may be wondering why we should use Pipes when we can use functions.

Criteria Pipe Function
Purpose Data transformation in the template Business logic and calculations
Use case Formatting, filtering, sorting, etc. Complex or multi-step calculations
Performance Pure pipes are efficient for transforming data only when needed Functions can be less performant when used in templates (requires manual calls)
Reusability Highly reusable across templates Functions are reusable within the component or service
Asynchronous Handling Handles observables and promises with AsyncPipe Requires manual subscription logic or use of 'async' in templates
Complexity Best for simple, declarative transformations Best for complex or dynamic logic
When to use When transforming data for display in the template When performing business logic or side effects that don't belong in the template

Types of Pipes
There are two types of Pipes.
Pure Pipe (Default): A pure pipe will only re-run when its input value changes.
    @Pipe({

      name: 'pureExample',

      pure: true // This is the default value, so you can omit this

    })

    export class PureExamplePipe implements PipeTransform {

      transform(value: any): any {

        console.log('Pure pipe executed');

        return value;

      }

    }


Impure Pipe: An impure pipe will re-run whenever Angular detects a change in the component’s state, even if the input value hasn’t changed.
@Pipe({
  name: 'impureExample',
  pure: false // Set to false to make it impure
})
export class ImpureExamplePipe implements PipeTransform {
  transform(value: any): any {
    console.log('Impure pipe executed');
    return value;
  }
}


In Angular, you can use in-built pipes or create your own.

In-built pipes

Angular provides some basic pipes that can be used.
It comes from the '@angular/common' package.

Some popular ones that can be helpful are:
CurrencyPipe, DatePipe, DecimalPipe, LowerCasePipe, UpperCasePipe and TitleCasePipe

How to use an in-built pipe?

In your ts file, define your variable. In our example, we will use the variable title.
title = 'app works!';

In your html, you can use the pipe as follows:
<h1> {{title | uppercase}} </h1>

The result is how the string title is displayed:

Note. The currency ‘USD’ is added in front because of the currency pipe, and only 10 characters are displayed because of the slide pipe.

Custom pipes

Run the command below to create a pipe file:
ng generate pipe <<pipe-name>>.

For example: ng generate pipe my-custom-pipe. Once executed, the two files below will be created

Open the file ‘my-custom-pipe.pipe.ts. You will see the following boilerplate code provided:
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'myCustomPipe'
})
export class MyCustomPipePipe implements PipeTransform {
  transform(value: any, args?: any): any {
    return null;
  }
}


After the default class, you can create the function for your new pipe. In our case, we will create a pipe that will replace spaces in a hyphen. It is important to add the decorator ‘@Pipe’ before the class so that Angular knows what follows will be a pipe. Also, pass the name of the pipe as a parameter in the ‘@Pipe’ decorator. Also, when creating the class, implement ‘PipeTransform’. The resulting class will be as follows:
@Pipe({name: 'removeWhiteSpace'})
export class RemoveWhiteSpacePipe implements PipeTransform {
  transform(value: string): string {
    return value.replace(/\s+/g, '-');
  }
}


The resulting class will be as follows (the full code):
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'myCustomPipe'
})
export class MyCustomPipePipe implements PipeTransform {


  transform(value: any, args?: any): any {
    return null;
  }
}

@Pipe({name: 'removeWhiteSpace'})
export class RemoveWhiteSpacePipe implements PipeTransform {
  transform(value: string): string {
    return value.replace(/\s+/g, '-');
  }
}


In the ts file of your component, create the variable that will hold the value that will be transformed
textWithSpaces = 'This is a text with a lot of spaces that will be transformed';

In the html file of your component, do the following:
<p>{{ textWithSpaces | removeWhiteSpace }}</p>

The result is the following:

Conclusion
An effective and potent method for formatting and transforming data in the templates of your application is to use angular pipes. Without having to code repetitious logic in your components, you can quickly manipulate data types like strings, dates, and numbers by utilizing built-in pipes. More freedom is provided by custom pipelines, which let you design modular, reusable, and maintainable transformation logic that is suited to your particular requirements.

Understanding the distinction between pipes and functions is key to leveraging their full potential. While functions provide a direct way to execute code, pipes offer a declarative approach to handle transformations directly within templates, improving readability and performance.

Whether you're working with Angular’s built-in pipes or creating custom ones, the ability to easily manipulate data in the view layer is a significant advantage in building dynamic and user-friendly applications. By mastering Angular pipes, you can keep your code clean, concise, and aligned with best practices, ultimately leading to more maintainable and scalable applications.

With the knowledge of how to use and create pipes, you’re now equipped to enhance your Angular applications with powerful data transformations, making your development experience more efficient and enjoyable.



AngularJS Hosting Europe - HostForLIFE.eu :: In VS Code by Debuggers for Chrome New

clock December 16, 2024 06:13 by author Peter

More than four years ago, on January 15, 2021, Debugger for Chrome wrote the post Debug Angular (1) in VS Code. With 208K readings, that article is really popular. This indicated that while Angular is a very popular tool for web development, it is difficult to persuade many developers to focus on its devugging technology. Although this article is a supplement to the original, I am aware that the Visual Studio Code Debugger for Chrome has been deprecated. We'll check if the original article is still relevant or valid.

Debug Angular in VS Code
Now the current VS Code is with v1.95.3. The VS Code Debugger for Chrome is deprecated:

However, user is introduced to use the JavaScript Debugger extension instead. Click the link, we can see that

this extension is already installed if you use VS Code or Visual Studio:

And furthermore,

Nightly Extension you may want to install our nightly build to get the latest fixes and features. The nightly build runs at 5PM PST on each day that there are changes. You can get Nightly extension from JavaScript Debugger (Nightly) - Visual Studio Marketplace, or search in VS Code extension for
@id:ms-vscode.js-debug-nightly

Debugging in VS Code

Actually, the debugging is the same way as we introduced in article, Debug Angular (1), In VS Code by Debugger for Chrome, we will not repeat the process, but given here the major points:

Configure the launch.json file --- choose the port as your app running

Run the app from the Angular CLI (very important, otherwise, the debugging will not work) by command.
Strat to debug.



AngularJS Hosting Europe - HostForLIFE.eu :: Create Customer and Process Card Payments with Tokenization Angular

clock December 11, 2024 06:41 by author Peter

In the following article we will be looking into credit card payment and credit card design using the Stripe element. Stripe is one of the online and in-person payment processing systems. It's not open source. In the below sample, we are using the test version. We can do operations like creating a customer, payment, custom UI element design using the Stripe card element, etc.

In the below sample, I have used the stripe.js npm package for Stripe payment processing in Angular and Stripe REST APIs. And for business logic, I have used the dot net in this article. I have defined back-end functionality.

Package Installation
Use the below npm command to install Stripe in Angular.
npm install @stripe/stripe-js

Create a customer using card tokenization
Creates a new customer in the Stripe system, associating a payment source; basically, it will create a customer after getting card info from users.

In this sample I am using a modal popup to get the card info.

creditcard.component.html
In the below sample, we are loading the card number, expiry date and CVV using stripe element.
<div class="modal-body">
    <!-- Modal content area -->
    <h2>Enter Your Credit Card Information</h2>
    <!-- Title -->

    <form (ngSubmit)="onSubmit()">
        <!-- Angular form submission handler -->

        <!-- Card Number -->
        <label for="card-number">Card Number</label>
        <!-- Label for card number -->
        <div id="card-number" class="stripe-element"></div>
        <!-- Stripe Element placeholder for Card Number -->

        <!-- Expiry Date -->
        <label for="card-expiry">Expiration Date</label>
        <!-- Label for expiration date -->
        <div id="card-expiry" class="stripe-element"></div>
        <!-- Stripe Element placeholder for Expiration Date -->

        <!-- CVC -->
        <label for="card-cvc">CVC</label>
        <!-- Label for CVC -->
        <div id="card-cvc" class="stripe-element"></div>
        <!-- Stripe Element placeholder for CVC -->

        <!-- Errors -->
        <div id="card-errors" role="alert"></div>
        <!-- Placeholder to show card input errors -->

        <!-- Buttons -->
        <div class="modal-buttons">
            <!-- Button container -->
            <button type="button" (click)="vm.closeCardModal()">Cancel</button>
            <!-- Button to cancel the modal -->
            <button type="submit" [disabled]="isSubmitting">Submit</button>
            <!-- Submit button, disabled while `isSubmitting` is true -->
        </div>
    </form>
</div>

creditcard.component.scss
.modal-body {
    background-color: #f9f9f9;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    max-width: 400px;
    margin: auto;
}
.modal-content {
  background: #fff;
  padding: 20px;
  border-radius: 8px;
  width: 400px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  text-align: center;
}

.modal-buttons {
  display: flex;
  justify-content: space-between;
  margin-top: 20px;
}

.requiredIndicate {
color: red; font-weight: bold;
}
h2 {
    text-align: center;
    color: #333;
}

form {
    display: flex;
    flex-direction: column;
}
.error-message{
    font-size: 15px;
    color: #df0707;
    padding: 2px;
}
label {
    margin-top: 10px;
    color: #555;
}

input {
    padding: 10px;
    margin-top: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

button {
    margin-top: 20px;
    padding: 10px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button[type="submit"] {
    background-color: #28a745;
    color: white;
}

button[type="button"] {
    background-color: #dc3545;
    color: white;
}

button:hover {
    opacity: 0.9;
}
#card-errors {
  color: red;
  font-size: 0.9em;
  margin-top: 5px;
}

creditcard.component.ts
In Component, we are loading the Stripe element to our UI element using Id. Don't hardcode the publish and secret key in the front end. try to get from backend
The mount() method is used to attach a Stripe Element (such as cardNumber, cardExpiry, or cardCvc) to a specific DOM element in your HTML.
Each Stripe Element can only be mounted to one DOM element. If you need to move it to a new location, unmount it first using the unmount() method
loadStripe() The method is used to create an instance of the stripe using the publish key.
displayError() method used to bind the error message to an HTML element.
onSubmit() method used for form submission and external validation if need means.
the createToken method in Stripe.js is used to securely create a single-use token that represents a payment method (like a credit card). This token can then be sent to your server for processing a payment or saving card details

import { AfterViewInit, Component, EventEmitter, OnInit, Output } from '@angular/core';
import { loadStripe, Stripe, StripeCardCvcElement, StripeCardExpiryElement, StripeCardNumberElement, StripeElements } from '@stripe/stripe-js';

@Component({
  selector: 'app-creditcard',
  templateUrl: './creditcard.component.html', // HTML template for the component
  styleUrls: ['./creditcard.component.scss'] // SCSS styles for the component
})
export class CreditcardComponent implements OnInit, AfterViewInit {

  // Stripe API keys (publishable key for client-side usage)
  publishKey: string = ""; // Please replace your stripe publish key here.

  // Stripe objects
  stripe: Stripe | null = null; // Stripe instance
  elements: StripeElements | null = null; // Stripe Elements instance
  cardNumber: StripeCardNumberElement | null = null; // Card Number Element
  cardExpiry: StripeCardExpiryElement | null = null; // Expiry Date Element
  cardCvc: StripeCardCvcElement | null = null; // CVC Element

  isSubmitting: boolean = false; // Prevent duplicate submissions

  @Output() tokenGenerated = new EventEmitter<string>(); // Emit the generated token to parent component

  constructor() { }

  ngOnInit(): void {
    // Component initialization logic (if needed)
  }

  async ngAfterViewInit() {
    // Load the Stripe instance with the publishable key
    this.stripe = await loadStripe(this.publishKey);

    if (this.stripe) {
      // Initialize Stripe Elements
      this.elements = this.stripe.elements();

      // Define the custom styles for Stripe Elements
      const style = {
        base: {
          color: '#32325d', // Default text color
          fontFamily: '"Roboto", sans-serif', // Font family
          fontSize: '16px', // Font size
          '::placeholder': {
            color: '#aab7c4', // Placeholder text color
          },
        },
        invalid: {
          color: '#fa755a', // Invalid input text color
          iconColor: '#fa755a', // Invalid icon color
        },
      };

      // Create and mount the Card Number Element
      this.cardNumber = this.elements.create('cardNumber', { style });
      this.cardNumber.mount('#card-number');

      // Create and mount the Expiry Date Element
      this.cardExpiry = this.elements.create('cardExpiry', { style });
      this.cardExpiry.mount('#card-expiry');

      // Create and mount the CVC Element
      this.cardCvc = this.elements.create('cardCvc', { style });
      this.cardCvc.mount('#card-cvc');

      // Attach event listeners to handle real-time validation errors
      this.cardNumber.on('change', this.displayError.bind(this));
      this.cardExpiry.on('change', this.displayError.bind(this));
      this.cardCvc.on('change', this.displayError.bind(this));
    }
  }

  displayError(event: any) {
    // Handle real-time validation errors
    const displayError = document.getElementById('card-errors');
    if (displayError) {
      if (event.error) {
        displayError.textContent = event.error.message; // Show error message
      } else {
        displayError.textContent = ''; // Clear error message
      }
    }
  }

  async onSubmit() {
    // Ensure Stripe and card elements are initialized
    if (!this.stripe || !this.cardNumber) {
      console.error('Stripe or card elements not initialized');
      return;
    }

    this.isSubmitting = true; // Set submission state to true

    // Create a token for the card details
    const { token, error } = await this.stripe.createToken(this.cardNumber);

    if (error) {
      // Display error message if tokenization fails
      const displayError = document.getElementById('card-errors');
      if (displayError && error.message) {
        displayError.textContent = error.message;
      }
    } else {
      // Emit the token to the parent component
      this.tokenGenerated.emit(token?.id);

      // Close the modal (assumes `vm.closeCardModal()` is defined)
      this.vm.closeCardModal();
    }

    this.isSubmitting = false; // Reset submission state
  }
}


Sample Output of UI Element

 

Modal Popup Open/Close
ngx-bootstrap npm package was used to open and close the modal. I have used a modal popup in the payment component to open and close the modal, so I have included it in payment.module.ts and declartion included.

package installation
npm i ngx-bootstrap

Include ModalModule in required module like below,

payment.module.ts

@NgModule({
  declarations: [PaymentComponent,CreditcardComponent],
  imports: [
    CommonModule,ReactiveFormsModule,FormsModule,NgToggleModule,
    PaymentRoutingModule, ModalModule.forRoot(),
  ]
})


payment.component.ts

Used to generate customer from the emitted output function creditcard.component.ts it will trigger customer generation.
openCardModal(): Used to open the modal popup with creditcard.component.ts.

constructor(private modalService: BsModalService,private paymentService:PaymentService)
  {

  }
openCardModal = () => {
  // Opens the CreditcardComponent as a modal
  this.modalRef = this.modalService.show(CreditcardComponent, {
    animated: true, // Enables animation for the modal
    keyboard: false, // Disables closing the modal via the ESC key
    backdrop: 'static', // Prevents clicking outside the modal to close it
    initialState: {
      vm: this.vm, // Passes a custom `vm` object to the modal component's input
    },
  });

  // Subscribes to the `tokenGenerated` EventEmitter from the modal component
  this.modalRef.content.tokenGenerated.subscribe((token: string) => {
    this.createCustomerForToken(token); // Calls the function to handle token processing
  });
};

createCustomerForToken(token) method
This method processes the token emitted by the modal and uses it to create a customer by calling the paymentService
createCustomerForToken(token: string) {
  // Calls the `createCustomer` method in the payment service
  this.paymentService
    .createCustomer(
      this.paymentService.GenerateCustomer(
        this.cardDetails.Name, // Name of the cardholder
        this.cardDetails.CardNumber, // Card number (masked or partial if passed)
        token // Token generated from Stripe
      )
    )
    .subscribe((data: any) => {
      // You can handle the response here, e.g., show success messages
    });
}


closeCardModal Method
This method closes the modal when the operation is complete or canceled.
closeCardModal = () => {
  this.modalRef?.hide(); // Hides the modal if `modalRef` exists
};

OnInit Method
This method used to initialize the vm's property and method
ngOnInit(): void {
  this.vm = {
    cardHolderName: null,  // Placeholder for the cardholder's name input field (starts with null)
    cardNumber: null,      // Placeholder for the credit card number (starts with null)
    expiryDate: null,      // Placeholder for the card's expiry date (starts with null)
    cvv: null,             // Placeholder for the CVV input field (starts with null)

    // Methods to open and close the card modal
    openCardModal: this.openCardModal,  // Reference to the method that opens the credit card modal
    closeCardModal: this.closeCardModal, // Reference to the method that closes the modal
  };
}


payment.service.ts
Generate an object using the generate customer, and for REST APIs, I am using the previous article.  Create customers with a tokenization block to generate customers based on tokens.
var apiUrl = ""; should be end point of the service.
 return {
    Email: Email,                     // Use the passed 'Email' parameter
    Name: Name,                       // Use the passed 'Name' parameter
    Phone: "1234567890",               // Replace with the actual phone number if needed
    Description: "Customer for test",  // Replace with an appropriate description if needed
    SourceID: token                    // The token passed from payment process
  };

public createCustomer(customer: any) {
  return this.apiHandler.post(apiUrl + "/create-customer-with-tokenisation", customer);
}
 public GeneratePaymentIntent(amount:number,offSession:boolean,paymentMethodID:string)
  {
    return {
      amount:amount,
      paymentMethodID: paymentMethodID,
      customerId: null,
      offSession:offSession
    };
  }
  public createPaymentIntent(paymentMethod:any)
  {
    return this.apiHandler.post(apiUrl + "/create-payment-intent",paymentMethod);
  }
  public createPayment(amount:any)
  {
    return this.apiHandler.post(apiUrl + "/create-payment-intent-without-paymentmethod",{ amount: amount });
  }

Pay using a card with the customer and payment method
Payment template used to pay amount using credit card.
<ng-template #paymentTemplate>
  <div class="modal-header">
    <h3 class="modal-title">Payment Information</h3>
  </div>
  <div class="modal-body">
    <div class="modal-content">
      <form (submit)="handlePayment($event)">
        <label>
          Without PaymentMethod:
          <ng-toggle  [(ngModel)]="isPaymentMethod" name="toggle" required />
        </label>
        <label>
          Card Holder Name:
          <input type="text" [(ngModel)]="cardHolderName" name="cardHolderName" required />
        </label>
        <label>
          Amount:
          <input type="text" [(ngModel)]="amount" name="amount" required />
        </label>
        <div id="pay-card-element" class="card-element"><!-- Stripe Card Element --></div>
        <div id="pay-card-errors" role="alert"></div>
        <div class="pay-modal-buttons">
          <button type="button" class="btn btn-failure" (click)="closeCardModal()">Cancel</button>
          <button type="submit" class="btn btn-success" [disabled]="loading">Pay {{ amount | currency }}</button>
        </div>
      </form>
    </div>
  </div>
</ng-template>

payment.component.ts
In payment component, variable declaration and constructor, Don't hard code publish key and secret key in html side try to get from server side.
// Declaring a dynamic object for storing values related to the modal and card details.
vm: any = {};

// Secret key for server-side Stripe API communication (should not be exposed on the client-side).
secretKey: string = "";

// Publishable key used for client-side Stripe communication.
publishKey: string = "";

// ViewChild decorator for referencing the modal template.
@ViewChild('paymentTemplate') paymentModal!: TemplateRef<any>;

// The modal reference to control its visibility and behavior.
modalRef!: BsModalRef;

// Stripe object initialized for Stripe.js integration (holds the Stripe instance).
private stripe: Stripe | null = null;

// The card element used for securely collecting card details.
private cardElement: any;

// States for loading, error messages, and cardholder's name.
public loading = false;
public error = '';
public cardHolderName = '';

// Amount to be processed for payment.
public amount = 1;

// A flag to track if it's a payment method or another type of payment action.
isPaymentMethod: boolean = true;

// Constructor injecting modal service for modal control and payment service for backend communication.
constructor(private modalService: BsModalService, private paymentService: PaymentService) {}

// ngOnInit lifecycle hook, currently not used but reserved for any initialization logic.
ngOnInit(): void {
  // Any initialization logic goes here if needed.
}


loadStripe() method

This method initializes Stripe Elements for securely collecting payment details.

  • loadStripe(this.publishKey): Asynchronously loads Stripe.js with the public key for client-side operations.
  • this.stripe.elements(): Creates an instance of Stripe Elements which provides a secure method to collect card information.
  • this.cardElement.mount('#pay-card-element'): Mounts the cardElement (a Stripe UI element) into the DOM, allowing users to enter credit card information.

async loadStripe() {
  // Load Stripe.js with the public key for client-side operations.
  this.stripe = await loadStripe(this.publishKey);

  // Check if Stripe was successfully initialized.
  if (this.stripe) {
    // Initialize Stripe Elements, which will be used to securely collect card details.
    const elements = this.stripe.elements();

    // Create a 'card' element for collecting card details, hiding postal code field.
    this.cardElement = elements.create('card', {
      hidePostalCode: true
    });

    // Mount the card element onto the HTML element with id 'pay-card-element' to display it on the page.
    this.cardElement.mount('#pay-card-element');
  } else {
    // Log an error if Stripe is not initialized properly.
    console.error('Stripe is not initialized');
  }
}

handlePayment() Method

This method handles the payment process, triggered when the user submits the payment form

  • event.preventDefault(): Prevents the form submission to allow custom handling via JavaScript.
  • this.paymentService.createPayment(this.amount): Calls a service to create a payment request with the backend, sending the payment amount.
  • this.stripe.confirmCardPayment(): Uses Stripe's API to confirm the payment using the card details entered by the user.
  • Error handling: Sets the error message if payment fails, and resets the loading state.
  • this.loading = false: Updates the loading state to stop the spinner once the payment process is finished.

async handlePayment(event: Event) {
  // Prevent default form submission behavior.
  event.preventDefault();

  // Set loading state to true to show a loading spinner or message.
  this.loading = true;

  // Check if Stripe is initialized before proceeding.
  if (this.stripe) {

    // Call the backend to create a payment, passing the amount to charge.
    this.paymentService.createPayment(this.amount).subscribe(async (data: any) => {

      // Ensure Stripe is initialized before proceeding with payment confirmation.
      if (this.stripe) {
        // Use Stripe to confirm the payment using the card details and secret key.
        const { error } = await this.stripe.confirmCardPayment(this.secretKey, {
          payment_method: {
            card: this.cardElement, // The card element that holds the user's card information.
            billing_details: {
              name: this.cardHolderName, // The name of the cardholder.
            },
          },
        });

        // Handle error if payment confirmation fails.
        if (error) {
          this.error = error.message ? error.message : 'An unknown error occurred';
          this.loading = false; // Reset loading state.
        } else {
          this.error = ''; // Clear any previous errors.
          this.loading = false; // Reset loading state.
        }
      } else {
        // Error handling if Stripe is not initialized.
        this.error = 'Stripe is not initialized';
        this.loading = false; // Reset loading state.
      }
    });

  } else {
    // Error handling if Stripe is not initialized.
    this.error = 'Stripe is not initialized';
    this.loading = false; // Reset loading state.
  }
}

openpaymentModal() Method
This method opens the payment modal where the user can enter payment details.
openpaymentModal = () => {
  // Show the modal using the BsModalService, passing the initial state with the modal data.
  this.modalRef = this.modalService.show(this.paymentModal, {
    animated: true, // Enable animations for the modal.
    keyboard: false, // Disable closing the modal via the keyboard.
    backdrop: 'static', // Prevent closing the modal by clicking outside.
    initialState: {
      vm: this.vm // Pass initial data (vm) to the modal component.
    }
  });

  // Call loadStripe to initialize Stripe and display the payment form inside the modal.
  this.loadStripe();
}


Full code snippet of payment.compoent.ts
import { trigger, state, style, transition, animate } from '@angular/animations';
import { Component, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { CreditcardComponent } from '../creditcard/creditcard.component';
import { PaymentService } from './payment.service';
import { loadStripe, Stripe } from '@stripe/stripe-js';

@Component({
  selector: 'app-payment',
  standalone: false,
  encapsulation:ViewEncapsulation.None,
  templateUrl: './payment.component.html',
  styleUrl: './payment.component.scss'

})
export class PaymentComponent implements OnInit{

  vm: any={};
  secretKey:string ="sk_test_51Q2TApRw3m8aFNMV8RYvLabAEmwYOwHtiNWXrP1pR88IlVeuItDrhoxbb80YcCm45BoN9ncle0Mw84wv74Vc4rV700Y0gwbdh7";
  publishKey:string ="pk_test_51Q2TApRw3m8aFNMVKcnlDcs0EH3pu0EuhPpKyYe99eaBXE2ex9Nd1aSkCi4dxZQ3jBZwjlyrUAU30RN8nuGth6dv00HGMKk8vH";


  @ViewChild('paymentTemplate') paymentModal !: TemplateRef<any> ;
  modalRef!: BsModalRef;
  private stripe: Stripe | null = null;
private cardElement: any;
public loading = false;
public error = '';
public cardHolderName = '';
public amount = 1;
 isPaymentMethod:boolean =true;
  constructor(private modalService: BsModalService,private paymentService:PaymentService)
  {

  }

  ngOnInit(): void {
    this.vm = {
      cardHolderName: null,
      cardNumber: null,
      expiryDate: null,
      cvv: null,
      openCardModal: this.openCardModal,
      closeCardModal: this.closeCardModal,
    };
  }

  openCardModal=()=> {
    this.modalRef = this.modalService.show(CreditcardComponent,{ animated: true,
      keyboard: false,
      backdrop : 'static',  initialState: {
        vm: this.vm
      }});
  this.modalRef.content.tokenGenerated.subscribe((token: string) => {
  this.createCustomerForToken(token);
  });
  }
  createCustomerForToken(token: string)
  {
    this.paymentService.createCustomer(this.paymentService.GenerateCustomer('', '', token)).subscribe((data: any) => {

    });
}
  closeCardModal=()=> {
    this.modalRef?.hide();
  }

async loadStripe() {
  this.stripe = await loadStripe(this.publishKey);
  if (this.stripe) {
    const elements = this.stripe.elements();
    this.cardElement = elements.create('card', {
      hidePostalCode: true
    });
    this.cardElement.mount('#pay-card-element');
  } else {
    console.error('Stripe is not initialized');
  }
}

async handlePayment(event: Event) {
  event.preventDefault();
  this.loading = true;

  if (this.stripe) {
    if(!this.isPaymentMethod){
      const { paymentMethod, error } = await this.stripe.createPaymentMethod({
        type: 'card',
        card: this.cardElement,
        billing_details: { name: this.cardHolderName },
      });

      if (error) {
        const displayError = document.getElementById('pay-card-errors');
      if (displayError && error.message) {
        displayError.textContent = error.message;
        this.loading = false;
      }
      } else {
        // Send payment method to backend

        this.makePayment(paymentMethod.id);
      }
    }
    else
    {
      this.paymentService.createPayment(this.amount).subscribe(async (data: any) => {

      if (this.stripe) {
        const { error } = await this.stripe.confirmCardPayment(this.secretKey, {
          payment_method: {
            card: this.cardElement,
            billing_details: {
              name: this.cardHolderName,
            },
          },
        });

        if (error) {
          this.error = error.message ? error.message : 'An unknown error occurred';
          this.loading = false;
        } else {
          this.error = '';
          this.loading = false;
        }
      } else {
        this.error = 'Stripe is not initialized';
        this.loading = false;
      }
    });
    }
  } else {
    this.error = 'Stripe is not initialized';
    this.loading = false;
  }

}

makePayment(paymentMethodId: string) {
  this.paymentService.createPaymentIntent(this.paymentService.GeneratePaymentIntent(this.amount, false, paymentMethodId)).subscribe((data: any) => {

  });
}
openpaymentModal=()=> {
  this.modalRef = this.modalService.show(this.paymentModal,{ animated: true,
    keyboard: false,
    backdrop : 'static',  initialState: {
      vm: this.vm
    }});
    this.loadStripe();
}
}


Sample UI

Conclusion
This approach enables the creation of a robust payment system integrated with Stripe, giving you the ability to scale and manage payments efficiently within your application. Attached is the sample code.



AngularJS Hosting Europe - HostForLIFE.eu :: Understanding Service, Factory, And Provider

clock December 6, 2024 07:39 by author Peter

In this section, we will endeavor to comprehend the most frequently confounding elements and usefulness of AngularJS Service, Factory, and Provider.


Basic Understanding
AngularJS Service, Factory, or Provider are all utilized for a similar reason; i.e., for making utility capacity that can be utilized all through the page with the infused capable question. Be that as it may, the way it is made and the way it is utilized are unique. Here, we should attempt to comprehend them unmistakably.

Service

Service is utilized for imparting utility capacities to the Service reference in the controller. Service is a singleton in nature, so for one's benefit, just a single case is made in the program and a similar reference is utilized all through the page. In the Service, we make work names as properties with this question.

Factory

The reason for Factory is likewise the same as Service, however for this situation, we make another protest and include works as properties of this question and toward the end, we restore this protest.

Provider

The reason for this is again the same, however, Provider yields $get work.

Presently let's endeavor to comprehend Service, Factory, and Provider by making and utilizing them.

How to make a Service, Factory, and a Provider. To start with, we have made a module.

Next is the Service creation where we have made a service utilizing the .benefit strategy. Notice that in the service, the two capacities "Hi" and "Total" have been made on "this" question.

At that point, we have made a factory strategy. Here, we have made the two capacities "Hi" and "Aggregate" on the new "factoryObject" and afterward we are restoring that protest toward the finish of the factory strategy.

In the last, we have made a provider utilizing the .provider technique in which we are restoring a protest having two capacities "Hi" and "Aggregate" to the $get work.

Create a module
var myApp = angular.module("myApp", []);

Create a service function
app.service("toDoService", function () {
    this.toDo = function () {
        return "Hi";
    };
    this.Add = function (x, y) {
        return x + y;
    };
});

Create a factory function

app.factory("toDoFactory", function () {

    var todofactoryObject = {};
    todofactoryObject.Hi = function () {
        return "Hi";
    };
    todofactoryObject.Add = function (x, y) {
        return x + y;
    };
    return todofactoryObject;
});

Create a provider function
app.provider("todoProvider", function() {
    this.$get = function() {
        return {
            Hi: function() {
                return "Hi";
            },
            Add: function(x, y) {
                return x + y;
            }
        };
    };
});

Notice that regardless of that, every one of the three has similar capacities "Hi" and "Whole" having the same usefulness, however, the method for presentation is unique. This is the real contrast between Service, Factory, and Provider.

Utilizing Service, Factory, and Provider

To utilize them basically infuse those into the controller definition and begin utilizing those references to call capacities "Hi" and "Total" characterized in them.

Beneath the code bit it is truly straightforward. We are essentially calling "Hi" and "Whole" capacities characterized by particular Service, Factory, and Provider reference objects.
myApp.controller("todoController", function($scope, todoService, todoFactory, todoProvider) {
    // service call
    $scope.todoService = function() {
        $scope.resultt = todoService.Hi();
    };
    $scope.addFunc = function() {
        $scope.result = todoService.Add(4, 5);
    };
    // factory call
    $scope.todoFactory = function() {
        $scope.result = todoFactory.Hi();
    };
    $scope.AddFactory = function() {
        $scope.result = todoFactory.Add(4, 5);
    };
    // provider call
    $scope.todoProvider = function() {
        $scope.result = todoProvider.Hi();
    };
    $scope.addProvider = function() {
        $scope.result = todoProvider.Add(4, 5);
    };
});

<div ng-app="app" ng-controller="todoController">
    <h1>Service</h1>
    <button ng-click="todoService()">hi</button>
    <button ng-click="addService()">add</button>
    <div ng-bind="result"></div>

    <h1>Factory</h1>
    <button ng-click="todoFactory()">hi f</button>
    <button ng-click="addFactory()">add f</button>
</div>

<h1>Provider</h1>
<button ng-click="todoProvider()">hi p</button>
<button ng-click="AddProvider()">add p</button>
<div ng-bind="result"></div>
</div>


Summary
There is no distinction regarding yield/usefulness between Service, Factory, and Provider, however, the distinction comes when we attempt to make them. Every one of the three has diverse methods for creation and capacity executions.



AngularJS Hosting Europe - HostForLIFE.eu :: Change Style Dynamically in Various Ways Using AngularJS

clock November 20, 2024 09:53 by author Peter

This article explains how to change the style dynamically in various ways using AngularJS. AngularJS provides three different ways to change the style dynamically. People always search for methods to change their style dynamically, AngularJS can solve their problems in any of three ways.


Step 1. First of all, you need to add an external Angular.js file to your application, you can go to the AngularJS official site or download my source code and then fetch it or you can click on this link to download it: ANGULARJS.

After downloading the external file you need to add this file to the Head section of your application as in the following.
<head runat="server">
    <title></title>
    <script src="angular.min.js"></script>
</head>

Step 2. Now I will create some simple CSS classes to be applied dynamically, or you can say at runtime.
<style>
    .changeColor {
        color: blue;
    }
    .changeSize {
        font-size: 30px;
    }
    .italic {
        font-style: italic;
    }
</style>


Here I have created three classes, namely changeColor, changeSize, and italic. The first CSS Class is used for changing the color of the text to Blue, the second is for changing the text size and the last one is for making the Text Italic.

Now we have created the classes to be applied, we need to work on the ViewModel or design part of our application where simple coding needs to be done to apply the change in CSS.

First Method
In the first method, objects of the classes are created that are called using the ng-model, let's see this by implementing it in our application as in the following.
<p ng-class="{changeColor: Color, changeSize: Size, italic: Italic}">
    Changes Will be Seen in Me
</p>
<input type="checkbox" ng-model="Color"> Change Color (apply "changeColor" class)<br>
<input type="checkbox" ng-model="Size"> Change Size (apply "changeSize" class)<br>
<input type="checkbox" ng-model="Italic"> Make it Italic (apply "italic" class)


Here I have applied the CSS to a <p> Tag, and classes are applied using the ng-class directive, here in the ng-class you can see that I have created an object of each class such as for changeColor, "Color" is created. After this I applied the binding using the ng-model, I created three checkboxes and in each checkbox ng-model is applied, each ng-model provides the binding using the objects created in the ng-class.

So, If we check the first checkbox then the color of the text will change to Blue, similarly, if we check the second and third checkboxes then the text size and its style will change.

Let's see the output.

Output
As I run the application and check the checkboxes then this type of output will be seen.

Second Method
Now, I will show you the Second Method of applying the CSS dynamically. In this method, class names will be called to Apply the CSS.
<p ng-class="style">I Will Show Second Method</p>
<input type="text" ng-model="style" placeholder="Type: changeSize changeColor italic">


Here you can see that in the ng-class I have passed the complete style, since I have passed the style in ng-class it will call all the classes that are created in that style. Then I created a TextBox to which the style is bound using the ng-model, whatever name is provided in the TextBox, the same style will be applied to the text provided through the <p> tag. If the the name provided in the TextBox doesn't match the CSS Class than nothing will happen to the text and nothing will be applied.

Let's see the output.

Output


Third Method
Now, I will show you the Third Method for applying the CSS dynamically.

In this method, CSS classes will be called in the order they were created.
<p ng-class="[style1, style2, style3]">Using Array Syntax</p>
<input ng-model="style1" placeholder="Type: changeSize, changeColor or italic"><br>
<input ng-model="style2" placeholder="Type: changeSize, changeColor or italic"><br>
<input ng-model="style3" placeholder="Type: changeSize, changeColor or italic"><br>

Here you can see that I have applied the CSS to the <p> tag using the ng-class but this time I have called the classes by the order they were created, style1 is automatically bound to the first class, similarly style2 and style3 are bound to the second and third class. Then I created three Textboxes that are bound to style 1, 2, and 3 separately, whatever CSS name is provided in these textboxes, the same CSS class will be applied to the Text provided in the <p> tag.

Let's see the output.

Output

The complete code of this application is as follows.
<html ng-app xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
    <title></title>
    <script src="angular.min.js"></script>
    <style>
        .changeColor {
            color: blue;
        }
        .changeSize {
            font-size: 30px;
        }
        .italic {
            font-style: italic;
        }
    </style>
</head>
<body>
    <p ng-class="{changeColor: Color, changeSize: Size, italic: Italic}">Changes Will be Seen in Me</p>
    <input type="checkbox" ng-model="Color"> Change Color (apply "changeColor" class)<br>
    <input type="checkbox" ng-model="Size"> Change Size (apply "changeSize" class)<br>
    <input type="checkbox" ng-model="Italic"> Make it Italic (apply "italic" class)
    <hr>
    <p ng-class="style">I Will Show Second Method</p>
    <input type="text" ng-model="style" placeholder="Type: changeSize changeColor italic">
    <hr>
    <p ng-class="[stle1, stle2, stle3]">I Will Show Third Method</p>
    <input ng-model="stle1" placeholder="Type: changeSize, changeColor or italic"><br>
    <input ng-model="stle2" placeholder="Type: changeSize, changeColor or italic"><br>
    <input ng-model="stle3" placeholder="Type: changeSize, changeColor or italic"><br>
</body>
</html>



AngularJS Hosting Europe - HostForLIFE.eu :: RxJS Operator Essentials: Map, Tap, Filter, and More

clock November 14, 2024 09:21 by author Peter

If you've been working with Angular for a while and find some RxJS pipeable operators slightly confusing, we will explore these familiar operators here.


Great, let’s dive into this exciting topic.

What is an RxJS Operator?
RxJS ships with more than 100 operators.
These operators are one of the building blocks of RxJS.
It is handy for manipulating (process or transform) streams, which are data sequences over time.
Remember that operators are functions, and there are two types of operators.

Let’s see them one by one.

RxJS map Operator

The map function in RxJS is an operator that transforms each emitted value from an observable based on a provided function, returning a new observable with modified values.
Let us see an example.

Creation Operators
We won’t be exploring the creation operator, but it is essential to give an overview. Creation operators are functions that can create an Observable with some expected predefined behavior or by joining other Observables.

Here are some familiar creation operators: of, from, fromEvent, and range.

Let’s have one example.

import { Component, OnDestroy, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { from, Subscription } from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  title = 'RxJSOperators';
  subFrom$!: Subscription;

  public ngOnInit(): void {
    this.subFrom$ = from([2, 4, 6, 8]).subscribe({
      next: (item) => console.log(item),
      error: (err) => console.log(err),
      complete: () => console.log('completed')
    });
  }

  public ngOnDestroy(): void {
    this.subFrom$.unsubscribe();
  }
}

From our code example, we have seen that inside the ngOnInit, the from([2,4,6,8]) method creates an observable that emits each number in the array sequentially.

The subscribe method attaches an observer to this observable.

  • First, next, which logs each item emitted.
  • Second, error logs any errors if there’s one.
  • Third, complete which logs “completed” when the observable completes.

Although this is not the main topic of our article, it is a good thing to have an idea.

Pipeable Operators

Pipeable operators are the kind that can be piped to Observables.

Let’s see the syntax below.

observableInstance.pipe(operator);
or
observableInstance.pipe(operatorFactory());


Essentially, the operator and operatorFactory behave as a single method in RxJS. However, there’s a difference between the two. Operator factories are functions that accept parameters to configure their behavior and immediately return operator functions.

Operator functions are the results of these calls (configured functions), which can then transform the observable’s data inside the .pipe().

Let’s see code examples of pipeable operators in the next sections.

RxJS map Operator

The map function in RxJS is an operator that transforms each emitted value from an observable based on a provided function, returning a new observable with modified values.

Let us see an example.


import { Component, OnDestroy, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { from, map, Subscription } from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  title = 'RxJSOperators';
  subCustomer1!: Subscription;

  public ngOnInit(): void {
    const customer$ = from([
      { id: 1, jerseyNumber: 23, age: 61, fullName: "Michael Jordan" },
      { id: 2, jerseyNumber: 23, age: 43, fullName: "Lebron James" },
      { id: 3, jerseyNumber: 24, age: 89, fullName: "Kobe Bryant" }
    ]);

    this.subCustomer1 = customer$
      .pipe(
        map(item => ({
          ...item, shoe: "Nike"
        }))
      )
      .subscribe((result) => console.log(result, "Added Nike shoes"));
  }

  public ngOnDestroy(): void {
    this.subCustomer1.unsubscribe();
  }
}

From our example, the map operator transforms each customer object by adding a new property, shoe, with a value of "Nike". Then, each customer object is spread (...item) to retain the existing properties while adding the shoe property, resulting in a new object.

Finally, log the result to the console with a message saying, "Added Nike shoes". Let’s see the output below.

RxJS tap Operator
The tap function in RxJS is an operator that allows you to perform side effects, like logging or debugging, on each emitted value without altering the observable’s values.

Let us see an example.
import {Component, OnDestroy, OnInit} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {filter, from, map, Subscription, tap} from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements  OnInit, OnDestroy {
  title = 'RxJSOperators';
  subCustomer2!: Subscription;
  public ngOnInit() {
    const customer$ = from([
              { id: 1, jerseyNumber: 23, age: 61, fullName: "Michael Jordan"},
              { id: 2, jerseyNumber: 23, age: 43, fullName: "Lebron James"},
              { id: 3, jerseyNumber: 24, age: 89, fullName: "Kobe Bryant"}
               ]);

    this.subCustomer2 = customer$.pipe(
      tap(item => console.log(item, "Debugging this item before putting Nike shoes")),
      map(item => ({
       ...item, shoe: "Nike"
      })),
      tap(item => console.log(item, "Debugging this item after putting Nike shoes")))
      .subscribe((result) => { console.log(result, "Final result"); });
  }
  public ngOnDestroy() {
    this.subCustomer2.unsubscribe();
  }
}


The first tap operator logs each customer object to the console before transforming. This is useful for debugging, allowing you to inspect the original data emitted by the customer.

Each item is logged with the message "Debugging this item before putting Nike shoes". The map operator transforms each customer object by adding a new property, shoe, with a value of "Nike".

As discussed in the previous example, this operation uses object spread (...item) to retain the original properties while adding the new shoe property, resulting in a modified object for each customer.

The second tap operator logs each transformed customer object, allowing you to verify that the shoe property has been successfully added.

Each item is logged with the message "Debugging this item after putting Nike shoes".

Finally, the subscribe method listens to the transformed observable.

For each item, it logs the final transformed result along with the "Final result" to indicate the completion of the transformation.

Let’s see the output below.

 

RxJS filter Operator
The filter function in RxJS is an operator that emits only the values from an observable that passes a specified condition, effectively filtering out values that don’t meet the criteria.

Let us see an example.
import {Component, OnDestroy, OnInit} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {filter, from, map, Subscription, tap} from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements  OnInit, OnDestroy {
  title = 'RxJSOperators';
  subCustomer3!: Subscription;

  public ngOnInit() {

    const customer$ = from([
               { id: 1, jerseyNumber: 23, age: 61, fullName: "Michael Jordan"},
               { id: 2, jerseyNumber: 23, age: 43, fullName: "Lebron James"},
               { id: 3, jerseyNumber: 24, age: 89, fullName: "Kobe Bryant"}
               ]);

    this.subCustomer3 = customer$.
                             pipe(filter( item => item.jerseyNumber === 23)).
                              subscribe((result) => { console.log(result); });

  }

  public ngOnDestroy() {

    this.subCustomer3.unsubscribe();
  }
}


The filter(item => item.jerseyNumber === 23) filters the data, allowing only objects where jerseyNumber is 23 to pass through the stream. In this example, Michael Jordan and LeBron James meet this condition, while Kobe Bryant does not.

Let’s see the output below.

RxJS take Operator
The take function in RxJS emits only the first specified number of values from an observable and then completes.

Let us see an example.
import {Component, OnDestroy, OnInit} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {filter, from, map, Subscription, take, takeLast, tap} from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements  OnInit, OnDestroy {
  title = 'RxJSOperators';
  subCustomer4!: Subscription;

  public ngOnInit() {

    const customer$ = from([
               { id: 1, jerseyNumber: 23, age: 61, fullName: "Michael Jordan"},
               { id: 2, jerseyNumber: 23, age: 43, fullName: "Lebron James"},
               { id: 3, jerseyNumber: 24, age: 89, fullName: "Kobe Bryant"}
               ]);

    this.subCustomer4 = customer$.
    pipe(
        filter( item => item.jerseyNumber === 23),
        take(1)
        ).
    subscribe((result) => { console.log(result); });

  }

  public ngOnDestroy() {

    this.subCustomer4.unsubscribe();
  }
}

The filter(item => item.jerseyNumber === 23), filters the data to only include customers with a jerseyNumber of 23. This will allow only Michael Jordan and LeBron James through the stream. While take(1) operator limits the stream to emit only the first item that passes the filter condition.

After emitting this first item, it automatically completes the Observable.

Let’s see the output below.

RxJS takeLast Operator
The takeLast function emits only the last specified number of values after the source observable completes.

Let us see an example.
import {Component, OnDestroy, OnInit} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {filter, from, map, Subscription, take, takeLast, tap} from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements  OnInit, OnDestroy {
  title = 'RxJSOperators';
  subCustomer5!: Subscription;

  public ngOnInit() {

    const customer$ = from([
               { id: 1, jerseyNumber: 23, age: 61, fullName: "Michael Jordan"},
               { id: 2, jerseyNumber: 23, age: 43, fullName: "Lebron James"},
               { id: 3, jerseyNumber: 24, age: 89, fullName: "Kobe Bryant"}
               ]);

    this.subCustomer5 = customer$.
      pipe(takeLast(1)).
      subscribe((result) => { console.log(result); });

  }
  public ngOnDestroy() {

    this.subCustomer5.unsubscribe();
  }
}


The take last operator is used to emit only the last item from the Observable. In this example, takeLast(1) will only emit the very last item in the list—{ id: 3, jersey number: 24, age: 89, fullName: "Kobe Bryant" }—and then complete the Observable.

Summary
In this post, we have discussed RxJS operators and shown the types of operators, such as pipeable and creation operators. We have seen examples of map, tap, filter, take, and takeLast operators. I hope you have enjoyed this article as much as I have enjoyed writing it. Stay tuned for more information, and don't forget to download the attached project source code. If you run the project source code, don’t forget to command “npm install.” Until next time, happy programming, and good luck with your career!



Visual Studio Hosting - HostForLIFE.eu :: Dev Tunnel in Visual Studio Simplifies Local Development

clock November 5, 2024 09:21 by author Peter

Dev Tunnel is a feature introduced in Visual Studio 2022 that simplifies remote debugging and collaboration for developers. It creates a secure tunnel between our local machine and a remote environment, allowing you to access your local applications remotely as if they were running on the remote machine.



This is useful for,

  • Remote debugging: You can set breakpoints, inspect variables, and step through your code as if you were working locally.
  • Collaboration: You can share your local applications with team members or clients, even if they don't have direct access to your development environment.
  • Testing on different devices: You can test your applications on various devices.

(e.g., mobile devices, IoT devices) without requiring them to be on the same network as your development machine.

To use Dev Tunnel

  • Make sure you have Visual Studio 2022 installed with the necessary workloads.
  • In Visual Studio, create a new tunnel by selecting Debug > Dev Tunnels > Create A Tunnel.

Choose the appropriate settings, such as the tunnel type (persistent or temporary) and the authentication method.

Start debugging: Start your application in debug mode, and the tunnel URL will be displayed in the Output window.
Access the application remotely: Use the tunnel URL to access your application from any device with an internet connection.

Dev Tunnel Types
Dev Tunnels come in two primary types, they are,

Temporary Tunnels

  • Created on-demand and exists only for the duration of a debugging session.
  • A new URL is generated each time you start a debugging session.
  • Ideal for quick testing and sharing without long-term access needs.

Persistent Tunnels

  • Remain active even after you close Visual Studio.
  • Maintain the same URL across multiple debugging sessions.
  • Suitable for scenarios where you need consistent access to your application, such as remote collaboration or continuous testing.

Different Types of Access
Dev Tunnels offer flexible access control options as follows,

  • Private
    • Only the creator of the tunnel can access it.
    • Ideal for personal projects or sensitive applications.
  • Organization
    • Members of the same organization as the creator can access the tunnel.
    • Useful for team collaboration within an organization.
  • Public
    • Anyone with the tunnel URL can access it.

Questions & Answers
Is a Microsoft account strictly necessary for accessing dev tunnels?


Yes, we do need a Microsoft account to use Dev Tunnels. This account is used for authentication and authorization purposes to ensure secure access to your local development environment.

Here are the reasons why a Microsoft account is required.

  • Security: By using a Microsoft account, you can control who has access to your Dev Tunnel and protect your sensitive data.
  • Authentication: The Microsoft account verifies your identity and grants you permission to create and use Dev Tunnels.
  • Account Management: Your Microsoft account allows you to manage your Dev Tunnels, including deleting them or modifying their settings.


To use Dev Tunnels, you can sign in with your Microsoft account, Microsoft Entra ID, or GitHub account. Once you're signed in, you can create and manage your Dev Tunnels.

Will the URL change if we close Visual Studio or stop debugging?

Yes, the Dev Tunnel URL will change if you close Visual Studio or stop debugging your application. This is because Dev Tunnels are typically temporary, meaning they are created on-demand and destroyed when the connection is closed.

However, you can create persistent tunnels that will maintain the same URL even after you close Visual Studio.
In conclusion, Dev Tunnel is a powerful tool that can significantly improve your development workflow by making remote debugging and collaboration easier and more efficient. If you're working with remote teams or need to test your applications on different devices, Dev Tunnel is definitely worth considering.



Visual Studio Hosting - HostForLIFE.eu :: VS Code Auto-Format Code on Save to Simplify Your Processes

clock October 30, 2024 09:27 by author Peter

For any developer, keeping code neat and orderly is essential, but worrying about formatting all the time can interfere with productivity. What if your code could be formatted automatically each time you hit save? This post will discuss a straightforward yet effective feature in Visual Studio Code (VS Code) that handles formatting for you with a single click.

Step-by-Step Guide: Enabling Format on Save
The magic of auto-formatting in VS Code lies in the "Format on Save" feature. Here's how you can enable it.

  • Open Visual Studio Code: Launch VS Code on your system.
  • Navigate to Settings: Click on `File` in the top menu, then select `Preferences` -> `Settings`.
  • Search for Format on Save: In the search bar, type "save" to filter the settings related to saving files. Look for the option labeled Format On Save. Look in the below image.

  • Enable the Feature: Check the box next to "Format On Save" to enable the feature.
    If you haven't selected a default formatter, VS Code will prompt you to choose one when you enable "Format on Save." You can pick from the available formats installed in your environment. For example, if you have Prettier installed, you can select it as your default formatter. Simply choose the one that suits your needs, and VS Code will use it to format your code every time you save.

The Magic of Auto-Formatting
Once you've enabled "Format on Save," you can write code without worrying about the formatting. Whether you're pasting in code snippets, writing redundant code, or simply speeding through a task, VS Code will ensure everything is clean and organized the moment you hit `CTRL+S`.

For example, imagine you write a block of redundant/dirty JavaScript code like this before Save click.

Without manually adjusting spaces or aligning braces or formatting, simply press `CTRL+S`, and VS Code will automatically format it.

See the magic; now, every time you click on save it'll automatically restructure the whole code.

Why Use Format on Save?

  • Consistency: Ensure consistent code style across your project without manual intervention.
  • Time-Saving: Focus more on logic and less on formatting, as VS Code handles the latter for you.
  • Error Reduction: Properly formatted code is easier to read and debug, reducing the likelihood of syntax errors.

Conclusion
With VS Code's "Format on Save" feature, you can keep your code neat and tidy with minimal effort. It’s a small setting that makes a big difference, letting you code faster and smarter. No need for additional tools—just code, save, and let VS Code do the rest. Give it a try, and experience the magic of auto-formatting in your next coding session.

Thanks a Lot, Everyone! Is this guide helpful? Give it a thumbs up and share it with your fellow developers! Your support keeps the tips and tricks coming.
Happy coding!



AngularJS Hosting Europe - HostForLIFE.eu :: Angular Directives 101

clock October 22, 2024 07:36 by author Peter

If you have been working with Angular directives for quite some time now, this article may help you as a refresher; if you are a beginner, this may get you started with Angular directives. We’ll try to break down the concept into its core parts and give easy examples to understand and approach.


Okay, then, let’s try to get started.

What is an Angular Directive?

Angular directives are HTML attributes that extend the behavior or the appearance of a standard HTML element. In other words, we can say that directives are simply instructions to the DOM. That’s why when we apply a directive to an HTML element or even an Angular component, we can add custom behavior or alter its appearance.
The excellent thing is that Angular provides a set of built-in directives that we can use in our components to cover most use cases.
These Angular built-in directives are part of the CommondModule.

So, we need to import CommonModule when we want to use them.

See an example of importing the built-in directives below.
import {NgForOf, NgIf, NgSwitch, NgSwitchCase} from '@angular/common';

For more information, you can check this official documentation https://v17.angular.io/api/common/CommonModule.

Types of Directives

We need to know the types of directives when dealing with Angular.

Let’s see them one by one.

Component Directives

These are directives with an associated template.
That’s why this is the commonly used directive in Angular application development.
Let’s see an example below.
import { Component } from '@angular/core';

@Component({
  selector: 'app-component-directives-sample',
  standalone: true,
  imports: [],
  templateUrl: './component-directives-sample.component.html',
  styleUrl: './component-directives-sample.component.css'
})
export class ComponentDirectivesSampleComponent {

}

From our example above, if you are already familiar with components and how to generate components.
That’s fundamentally it.
Just remember that all components are directives, but not all directives are components.
Components extend the concept of directives by providing a view (template) to render.

Structural Directives

Structural directives are used to manage the elements from the DOM, such as adding or removing elements. If a developer is building dynamic and interactive web applications with Angular, managing the display of elements based on certain conditions or iterating over a collection is essential.

Angular provides three powerful structural directives to handle these scenarios: *ngIf, *ngSwitch, and *ngFor.

Let’s dive into how these directives work and how to use them.
The *ngIf

This directive allows you to conditionally display or remove an element from the DOM based on a boolean expression.
If the condition is evaluated as true, the element is rendered; otherwise, it is removed from the DOM.
See the example below.

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

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [NgIf],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'sampleDirectives';
  showProduct: boolean = true;
  products:Array<any>= [
    { id: 1,
      name: "Intel Core i9-11900K",
      type: "CPU"
    },
    {
      id: 2,
      name: "AMD Ryzen 9 5950X",
      type: "CPU"
    }
  ];
}


app.component.html
<div *ngIf="showProduct">
  <h2 [innerText]="products[0].type"></h2>
  <p [innerText]="products[0].name"></p>
</div>

From our sample code, we have the showProduct set to true and a product array to hold dummy product data.
With this view, we have decided to get the first index item of the products array.
As a result, the HTML view will show the product type and the product name.
See the output below.

The *ngSwitch
As you can see, the *ngIf works excellent for a single condition, while *ngSwitch is more efficient when you need to toggle between multiple options.
It looks almost like a switch-case statement in programming, where you can choose between different elements to render based on an expression.

See the example below.

app.component.ts
import { Component } from '@angular/core';
import {NgForOf, NgIf, NgSwitch, NgSwitchCase} from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ NgIf, NgSwitch, NgSwitchCase, NgForOf],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'sampleDirectives';
  showProduct: boolean = true;
  products:Array<Product>= [
    { id: 1,
      name: "Intel Core i9-11900K",
      type: "CPU"
    },
    {
      id: 2,
      name: "AMD Ryzen 9 5950X",
      type: "CPU"
    },
    {
      id: 3,
      name: "EVGA SuperNOVA 850 G5",
      type: "Power Supply"
    },
    {
      id: 4,
      name: "G.Skill Ripjaws V Series 32GB",
      type: "Memory"
    }
  ];
  firstProduct: Product;
  secondProduct: Product;
  thirdProduct: Product;

  constructor() {
    this.firstProduct = this.products[0];
    this.secondProduct = this.products[1];
    this.thirdProduct = this.products[2];
  }
}

export class Product {
  id: number = 0;
  name: string = "";
  type: string = "";
}


app.component.html
<div [ngSwitch]="thirdProduct.type">
  <h2 [innerText]="thirdProduct.type"></h2>
  <p [innerText]="thirdProduct.name"></p>
  <p *ngSwitchCase="'CPU'">
    This product is a CPU.
  </p>
  <p *ngSwitchCase="'Memory'">
    This is a RAM (Random Access Memory).
  </p>
  <p *ngSwitchCase="'Power Supply'">
    This is a Power Supply.
  </p>
</div>


As a result, the HTML view will show the product type and the product name.

See the output below.

The *ngFor
I know what you are thinking if you have been dealing with programming. *ngFor is used to repeat an element for each item in a collection. Looks like a loop, right?
From our previous example, we won’t change “app.component.ts.”
We’ll add the *ngFor inside the app.component.html.
Let’s see an example below.

app.component.html
<div>
  <ul>
    <li *ngFor="let product of products">
        <h2 [innerText]="product.name"></h2>
        <p [ngSwitch]="product.type">
          <span *ngSwitchCase="'CPU'">
            This product is a CPU.
          </span>
          <span *ngSwitchCase="'Memory'">
            This is a RAM (Random Access Memory).
          </span>
          <span *ngSwitchCase="'Power Supply'">
            This is a Power Supply.
          </span>
        </p>
    </li>
  </ul>
</div>


As a result, the HTML view will show an unordered list of products.
See the output below.

Attribute Directives
Attribute directives modify the appearance of or define a custom behavior for a DOM element.
Angular has a rich set of built-in directives that allow dynamic styling and classes to be applied.
Among these directives, ngClass and ngStyle are essential tools for any Angular developer.

Let’s try to explore them one by one.

The ngClass
We can use this directive ngClass to add or remove CSS classes dynamically.
Moreover, developers can use this directive to apply one or more CSS classes to an element conditionally.
You can pass a string, array, or object to ngClass to control which classes should be added or removed.
You can use either the expression or method with the ngClass directive.

Using Expression
A developer can’t write if condition within the ngClass directive.

However, we can use the ternary operator as this is an expression.
//Syntax
[ngClass]="condition ? 'when true apply class' : 'when false apply class'"
//Syntax (multiple classes)
[ngClass]="condition ? 'when true apply class1 class2' : 'when false apply class1 class2'"


Let’s have an example below.
attribute-directive-samp.component.css

.dot {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  display: inline-block;
  background-color: #c1bbbb;
}
.dot-border-red {
  border-color: red;
  border-style: dotted;
  border-width: 3px;
}

.dot-border-yellow {
  border-color: yellow;
  border-style: dotted;
  border-width: 3px;
}
.yellow {
  background-color: yellow;
}

.red {
  background


attribute-directive-samp.component.ts
import { Component } from '@angular/core';
import {NgClass} from '@angular/common';

@Component({
  selector: 'app-attribute-directive-samp',
  standalone: true,
  imports: [
    NgClass
  ],
  templateUrl: './attribute-directive-samp.component.html',
  styleUrl: './attribute-directive-samp.component.css'
})
export class AttributeDirectiveSampComponent {
  isYellow = false;
  isRed: boolean = false;

  colorChanged(value:string): void {
    if(value === 'R'){
      this.isRed = true;
      this.isYellow = false;
    }
    else if(value === 'Y'){
      this.isYellow = true;
      this.isRed = false;
    }
  }
}

attribute-directive-samp.component.html
<h3>Using Expression</h3>
<input type="radio" name="firstDot" value="R" (change)="colorChanged('R')" /> Red
<input type="radio" name="firstDot" value="Y" (change)="colorChanged('Y')" /> Yellow
<br/>
<div class="dot" [ngClass]="isRed ? 'dot red dot-border-yellow': 'dot yellow dot-border-red'">
</div>

From our example, we have seen that we can change the circle’s background color and border when choosing between red and yellow.
We have achieved this by using an expression inside the ngClass.

Output


Using Function
Developers can apply CSS classes through various methods in complex conditions.

For example, you can use this way to set a CSS class based on user input.

Let’s see an example below.
attribute-directive-samp-using-function.component.css

.dot {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  display: inline-block;
  background-color: #c1bbbb;
}
.dot-border-red {
  border-color: red;
  border-style: dotted;
  border-width: 3px;
}

.dot-border-yellow {
  border-color: yellow;
  border-style: dotted;
  border-width: 3px;
}
.yellow {
  background-color: yellow;
}

.red {
  background-color: red;
}

attribute-directive-samp-using-function.component.ts
import { Component } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {NgClass} from '@angular/common';

@Component({
  selector: 'app-attribute-directive-samp-using-function',
  standalone: true,
  imports: [
    FormsModule,
    NgClass
  ],
  templateUrl: './attribute-directive-samp-using-function.component.html',
  styleUrl: './attribute-directive-samp-using-function.component.css'
})
export class AttributeDirectiveSampUsingFunctionComponent {
  selectedColor: string = "";

  getClassColorValue(): string {
    let classToReturn = '';
    if(this.selectedColor === 'Red'){
      classToReturn = 'dot red dot-border-yellow';
    }
    else if(this.selectedColor === 'Yellow'){
      classToReturn = 'dot yellow dot-border-red';
    }
    return classToReturn;
  }
}


attribute-directive-samp-using-function.component.html
<h3>Using Function</h3>
<input type="radio" name="secondDot" value="Red" [(ngModel)]="selectedColor" /> Red
<input type="radio" name="secondDot" value="Yellow" [(ngModel)]="selectedColor" /> Yellow
<br/>
<div class="dot" [ngClass]="getClassColorValue()"></div>


From our example, we have seen that we can change the circle’s background color and border when choosing between red and yellow.
However, instead of an expression, we used a method or function where the class was set inside the ngClass.
Note. For both examples, we use the same styles for attribute-directive-samp.component.css and attribute-directive-samp-using-function.component.css.
Again, we have achieved our goal for both examples, but by using different approaches, it's up to the developer to choose either expression or method/function.

Output

 

The ngStyle
Developers, when using the ngStyle directive, allow them to set the style property of the DOM element.

People suggest directly putting styles inside the style attribute isn’t that good.
But in our case, and for educational purposes, we need to understand that this directive is available for us to use in some cases.

Let’s see an example.

attribute-directives-ngstyle.component.ts

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

@Component({
  selector: 'app-attribute-directives-ngstyle',
  standalone: true,
  imports: [
    NgStyle,
    FormsModule
  ],
  templateUrl: './attribute-directives-ngstyle.component.html',
  styleUrl: './attribute-directives-ngstyle.component.css'
})
export class AttributeDirectivesNgstyleComponent {

  isBold : boolean = false;
  isItalic:boolean = false;
  isUpperCase: boolean = false;


  setElementStyle() {
    return {
      'font-weight': this.isBold ? 'bold' : 'normal',
      'font-style': this.isItalic ? 'italic' : 'normal',
      'text-transform': this.isUpperCase ? 'uppercase' : 'none'
    };
  }
}

attribute-directives-ngstyle.component.html

<p>
  Let us style the text below.
  <br/>
  Bold: <input type="checkbox" [(ngModel)]="isBold"  /> <br/>
  Italic: <input type="checkbox" [(ngModel)]="isItalic" /> <br/>
  UpperCase: <input type="checkbox" [(ngModel)]="isUpperCase" /> <br/>
</p>
<div [ngStyle]="setElementStyle()">I love Angular</div>


From our example, we have built an object that checks whether the checkboxes are checked, which makes the isItalic, isUpperCase, and isBold true or false with specific values at runtime.

Then, it will be returned as an object assigned to the ngStyle directive.

See the output below.


Summary
In this post, we have discussed the three types of directives: component, structural, and attribute. However, component directives seem straightforward to most of us developers. We have seen a lot of examples of structural and attribute directives, and the examples we have are the built-in directives for these types of directives built into the Angular library for most use cases. I hope you have enjoyed this article as much as I have enjoyed writing it.
Stay tuned for more information, and don't forget to download the attached project source code.
If you run the project source code, don’t forget to command “npm install.”
Until next time, happy programming, and good luck with your career!



European Visual Studio 2022 Hosting - HostForLIFE :: How to Fix the 'Process with an Id of #### is not Running' Error in Visual Studio?

clock October 15, 2024 08:00 by author Peter

Approach 1

  • Close Visual Studio: Ensure that Visual Studio is completely closed before proceeding.
  • Delete the Hidden .vs Folder
    • Navigate to the folder where your solution files are stored.
    • Find the hidden .vs folder and delete it. You may need to enable viewing hidden files in File Explorer to see this folder.
  • Delete the bin and obj Folders
    • Search within your project directory for the bin and obj folders.
    • Delete these folders to ensure that old build artifacts are cleared.
  • Restart Visual Studio: After deleting the folders, reopen Visual Studio.
  • Rebuild and Debug
    • Press F5 or click the "Start Debugging" button to rebuild the project.
    • IIS Express should load normally, allowing you to debug your application.

Approach 2
Open Visual Studio as Administrator: To avoid permission issues, right-click on the Visual Studio icon and select Run as administrator.

Unload the Project

  • In Solution Explorer, right-click on your project.
  • Click on Unload Project to temporarily unload it.

Edit the .csproj File
Right-click on the unloaded project again and select Edit PROJECT_NAME.csproj (replace PROJECT_NAME with the actual name of your project).
Remove the IIS Express Configuration

In the .csproj file, locate the following lines of code.
<DevelopmentServerPort>45678</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:45678/</IISUrl>

Delete these lines to remove the custom port settings.

Save and Close the .csproj File: After making the changes, save the file and close it.

Reload the Project
Right-click the unloaded project again and select Reload Project. By following these steps, you can reset your project's IIS Express configuration and resolve port-related issues.



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