Angular Archives - KarthikTechBlog https://karthiktechblog.com/category/angular/ Everyone can code! Wed, 05 Jan 2022 01:50:49 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.2 https://karthiktechblog.com/wp-content/uploads/2022/08/cropped-lsc-logo-png-new-3-32x32.png Angular Archives - KarthikTechBlog https://karthiktechblog.com/category/angular/ 32 32 How to implement time-based caching in Angular using HTTP Interceptor https://karthiktechblog.com/angular/how-to-implement-time-based-caching-in-angular-using-http-interceptor/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-implement-time-based-caching-in-angular-using-http-interceptor https://karthiktechblog.com/angular/how-to-implement-time-based-caching-in-angular-using-http-interceptor/#comments Wed, 05 Jan 2022 01:50:49 +0000 https://karthiktechblog.com/?p=1013 Introduction Implementing time-based caching in Angular using HTTP Interceptor is simple and easy. This post shows step by step process of creating simple caching logic for all outgoing HTTP GET API calls. Why implement caching? Angular is used to develop SPA applications. Most of the pages in an application will call external HTTP APIs (GET) […]

The post How to implement time-based caching in Angular using HTTP Interceptor appeared first on KarthikTechBlog.

]]>
Introduction

Implementing time-based caching in Angular using HTTP Interceptor is simple and easy. This post shows step by step process of creating simple caching logic for all outgoing HTTP GET API calls.

How to implement time-based caching in Angular using HTTP Interceptor

Why implement caching?

Angular is used to develop SPA applications. Most of the pages in an application will call external HTTP APIs (GET) to retrieve data in order to display it on the screen. Let’s say, a user navigates to the same page multiple times which is normal.

This will lead to calling the same GET API multiple times though the data is not changed. A typical example is to get a list of product categories on a page which won’t change so often or even if doesn’t change at all.

By implementing caching in the front end or we can say as client-side, we will avoid calling the same API often. This will save some network calls and since data is served from the local cache, the application will be faster and give a rich user experience.

Short video tutorial

What is HTTP Interceptor?

In simple words, HTTP Interceptor in Angular is used to intercept the outgoing HTTP API calls and perform some action. E.g. we can intercept the outgoing call and add or modify the request/response. HTTP Interceptors transform the outgoing request before passing it to the next interceptor in the chain, by calling next.handle(transformedReq).

To know more about HTTP Interceptor, refer here.

Implementation of Caching

First, we will create a service named “HttpCacheService” which does the below actions.

  1. Used to retrieve saved response of a particular URL.
  2. For any new outgoing request, used to save the URL and its response.
  3. Invalidate a particular URL response.
  4. Invalidate the entire cache.
import { Injectable } from '@angular/core';
import { HttpResponse } from '@angular/common/http';

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

  private requests: any = { };

  constructor() { }

  get(url: string): HttpResponse | undefined {
    return this.requests[url];
  }

  put(url: string, response: HttpResponse): void {
    this.requests[url] = response;
  }

  invalidateUrl(url: string): void {
    this.requests[url] = undefined;
  }

  invalidateCache(): void {
    this.requests = { };
  }

}

Implementing HTTP Interceptor

We will implement an HTTP interceptor named “CacheInterceptor

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpResponse,
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { HttpCacheService } from '../services/http-cache.service';


@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  constructor(
  private cacheService: HttpCacheService
  ) {}

  intercept(
    req: HttpRequest,
    next: HttpHandler
  ): Observable> {
    

    //check if the outgoing calls are GET and MRDH APIs
    if (req.method === 'GET' ) { 
      // attempt to retrieve a cached response
      const cachedResponse:
        | HttpResponse
        | undefined = this.cacheService.get(req.url);

      // return cached response
      if (cachedResponse) {
        console.log(`Returning a cached response: ${cachedResponse.url}`);
        console.log(cachedResponse);
        return of(cachedResponse);
      }

      // send request to server and add response to cache
      return next.handle(req).pipe(
        tap((event) => {
          if (event instanceof HttpResponse) {
            console.log(`Adding item to cache: ${req.url}`);
            this.cacheService.put(req.url, event);
          }
        })
      );
    }
    else {
        // pass along non-cacheable requests 
        return next.handle(req);
    }
  }
}

This interceptor will intercept all outgoing HTTP API calls. The Cache Interceptor will save the URL and its response detecting upon a GET API call. If we don’t find any saved response, we will let the call continue and save the response and its URL in our HttpCacheService.

To make this work we need to register this in the main NgModule provider.

Use this code to place it in the NgModule of the application.

providers: [
    { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }
  ]
.... other codes ignored

Great, that’s it. it’s as simple as that.

Wait wait. The title says time-based cache implementation. Right, let’s implement that next.

TimerService is used to start the timer when the first response is cached. After which the interceptor checks for a particular amount of time and invalidates the cache.

import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';

@Injectable({ providedIn: 'root' })
export class TimerService {
  private isTimerStarted = false;
  public dateNow = new Date();
  public dDay = new Date();
  milliSecondsInASecond = 1000;
  hoursInADay = 24;
  minutesInAnHour = 60;
  SecondsInAMinute = 60;

  public timeDifference: any;

  constructor() {}

  private getTimeDifference() {
    this.timeDifference = this.dDay.getTime() - new Date().getTime();    
  }
  
  startTimer() {
    if (!this.isTimerStarted) {
   
      this.dDay.setMinutes(
        this.dDay.getMinutes() + 30 //+environment.cacheTimeInMinutes // you can put this time in environment file to make it configurable.
      );
      this.getTimeDifference();
      this.isTimerStarted = true;
    }
  }

  resetTimer() {
    this.isTimerStarted = false;
    this.getTimeDifference();
  }

  getRemainingTime(): number {
    this.getTimeDifference();
    return this.timeDifference;
  }
}

Updated CacheInterceptor code which uses time service to track down the timing and invalidate the cache after a particular time.

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpResponse,
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { HttpCacheService } from '../services/http-cache.service';
import { TimerService } from '../services/timer.service';


@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  constructor(
  private cacheService: HttpCacheService,
  private timerService: TimerService
  ) {}

  intercept(
    req: HttpRequest,
    next: HttpHandler
  ): Observable> {
    
    this.timerService.startTimer();
    let remainingTimeInMilliseconds = this.timerService.getRemainingTime();
    
    if (remainingTimeInMilliseconds <= 0) {
      
      this.timerService.resetTimer();
      console.log(
        `Invalidating cache due to cache time limit: ${req.method} ${req.url}`
      );
      this.cacheService.invalidateCache();
    } 


    //check if the outgoing calls are GET and MRDH APIs
    if (req.method === 'GET' ) { 
      // attempt to retrieve a cached response
      const cachedResponse:
        | HttpResponse
        | undefined = this.cacheService.get(req.url);

      // return cached response
      if (cachedResponse) {
        console.log(`Returning a cached response: ${cachedResponse.url}`);
        console.log(cachedResponse);
        return of(cachedResponse);
      }

      // send request to server and add response to cache
      return next.handle(req).pipe(
        tap((event) => {
          if (event instanceof HttpResponse) {
            console.log(`Adding item to cache: ${req.url}`);
            this.cacheService.put(req.url, event);
          }
        })
      );
    }
    else {
        // pass along non-cacheable requests 
        return next.handle(req);
    }
  }
}

CacheInterceptor will monitor all the outgoing calls and start the triggers timer. After 30 minutes of time, the cache service will be ready to invalidate the cache. Interceptor invalidates the cache after 30 minutes of time. This is what will happen when the app initiates the first call.

Are you a beginner? Interested in learning Angular? check out this link

Summary

In this post, I showed you how to implement time-based caching in Angular using HTTP Interceptor. I hope you enjoyed this post and it is useful for you.

The post How to implement time-based caching in Angular using HTTP Interceptor appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/how-to-implement-time-based-caching-in-angular-using-http-interceptor/feed/ 1 1013
Angular Getting Started | Software Installation and App Setup | Part 2 https://karthiktechblog.com/angular/angular-getting-started-software-installation-and-app-setup-part-2/?utm_source=rss&utm_medium=rss&utm_campaign=angular-getting-started-software-installation-and-app-setup-part-2 https://karthiktechblog.com/angular/angular-getting-started-software-installation-and-app-setup-part-2/#respond Sat, 18 Dec 2021 18:29:14 +0000 https://karthiktechblog.com/?p=994 Overview In this post, I will cover software installation steps and app setup from scratch. Software Installations In this course, I introduce TypeScript, which is the programming language we’ll use. TypeScript is the language we use when working with Angular. Let me take a moment to tell you what is TypeScript. “TypeScript is JavaScript with […]

The post Angular Getting Started | Software Installation and App Setup | Part 2 appeared first on KarthikTechBlog.

]]>
Overview

In this post, I will cover software installation steps and app setup from scratch.

Angular Getting Started | Software Installation and App Setup

Software Installations

In this course, I introduce TypeScript, which is the programming language we’ll use.

TypeScript is the language we use when working with Angular. Let me take a moment to tell you what is TypeScript.

TypeScript is JavaScript with syntax for types.” TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.

check out more here

What is TypeScript?

1. TypeScript adds additional syntax to JavaScript to support a tighter integration with your editor. Catch errors early in your editor.

2. TypeScript code converts to JavaScript, which runs anywhere JavaScript runs: In a browser, on Node.js or Deno and in your apps.

3. TypeScript understands JavaScript and uses type inference to give you great tooling without additional code.

typescriptlang.org

JavaScript:

JavaScript is the language for the web and is executed by all browsers. The JavaScript language specification standard is officially called ECMAScript, or ES.


Most modern browsers support ES5. ES 2015 is renamed from ES6 specification. It introduced many key new features, such as classes and arrow functions.

Any newer JavaScript features that we use but a browser doesn’t support must first be transpiles. Newer JavaScript features in our code must be compiled by a tool that converts the newer JavaScript syntax to comparable older syntax before the browser executes it.

Microsoft developed TypeScript which is open-source. It is a superset of JavaScript, meaning all JavaScript is valid TypeScript. TypeScript code transpiles to plain JavaScript.

Installing IDE Editor:

There are many editors that support TypeScript, either out of the box or with a plugin. We’ll select one of the most common editors used by Angular developers, Visual Studio Code, often just called VS Code.

Download Visual Studio Code

Installing NPM:

We need to install npm (Node Package Manager) before we begin. Npm has become the package manager for JavaScript applications. With npm, we can install libraries, packages, and applications, along with their dependencies. We’ll need npm to install all the libraries for Angular.

Download and install Node.JS here

Install the Angular CLI

To install the Angular CLI, open a terminal window and run the following command:

npm install -g @angular/cli

Create a workspace and initial application

Run the CLI command ng new and provide the name my-app, as shown here

ng new my-app

Run the application

The Angular CLI includes a server, for you to build and serve your app locally.

  1. Navigate to the workspace folder, such as my-app.
  2. Run the following command
cd my-app
ng serve --open

The ng serve command launches the server watches your files and rebuilds the app as you make changes to those files.

The –open (or just -o) option automatically opens your browser to http://localhost:4200/. In case you need to run on a different port, use –port <port number> E.g. –port 4300

If your installation and setup were successful, you should see a page similar to the following.

Angular Getting Started | default app setup

Short video tutorial

Summary

Hope you enjoyed learning this part of the course. This post explained the software required to be installed in our system to get started with angular application development.

The post Angular Getting Started | Software Installation and App Setup | Part 2 appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/angular-getting-started-software-installation-and-app-setup-part-2/feed/ 0 994
Angular Getting Started | Course overview and Introduction | Part 1 https://karthiktechblog.com/angular/angular-getting-started-course-overview-and-introduction-part-1/?utm_source=rss&utm_medium=rss&utm_campaign=angular-getting-started-course-overview-and-introduction-part-1 https://karthiktechblog.com/angular/angular-getting-started-course-overview-and-introduction-part-1/#respond Sat, 18 Dec 2021 14:48:29 +0000 https://karthiktechblog.com/?p=989 Overview Angular Getting Started is a beginner-level course that takes you on a journey through the basic features of Angular. The course will guide you through the right path and make you feel more pleasant and productive. In this course, we build a sample application E.g. Restaurant. so you can code along or use it […]

The post Angular Getting Started | Course overview and Introduction | Part 1 appeared first on KarthikTechBlog.

]]>
Overview

Angular Getting Started is a beginner-level course that takes you on a journey through the basic features of Angular. The course will guide you through the right path and make you feel more pleasant and productive.

Angular Getting Started | Course overview and Introduction


In this course, we build a sample application E.g. Restaurant. so you can code along or use it as a reference for your own development. Also, you will see how Angular provides a consistent set of patterns for building components, templates, modules, and services which will help come up to speed quickly.

This course covers the following

  1. Setup local development environment starting from stratch.
  2. How to build components
  3. How to create the user interface for your application in a template, and power it up with data binding and directives.
  4. Build services for logic needed across components and inject those services where they are needed.
  5. Learn how to send requests to a web server using HTTP and observables.
  6. Set up routing to navigate between the views of your application
  7. Last but not least, during the course you will learn Angular command line interface, or CLI, to generate, execute, test, and at the end how to deploy your Angular application.

At the end of the course, you will know the basics you need to get started building your own Angular applications.

Introduction

Angular is a framework for building both small and large web applications. With Angular, you can build a simple, small website in a few hours or build rich full-featured enterprise-level product management and inventory application.


Angular is a JavaScript framework for building client-side applications. These are applications that run entirely in the user’s browser. We use techniques we already know including HTML and CSS to build the user interface, and we write our code in TypeScript, which is an enhanced version of JavaScript.

Why Angular and not some other JavaScript framework?

There are a lot of other JavaScript frameworks out there however, Angular makes our HTML more expressive.


We can embed features, such as if conditions, for loops, and local variables, directly into our HTML. Angular has powerful data binding that lets us connect data directly to our UI. Angular promotes modularity.

We build our applications as a set of building blocks, making it easier to create and reuse content. And Angular has built‑in support for communication with a back‑end server.


This makes it easy for our web applications to get and post data or execute server‑side business logic.

Angular Getting Started

This is a beginner-level course/tutorial. However, this course assumes you have some basic knowledge of JavaScript for code, HTML for building a user interface, and Cascading Style Sheets, or CSS for styling.


You do not need any prior knowledge of Angular or TypeScript. We’ll cover what you need in this course. If you have a working knowledge of each of these will help you learn this course faster.

Whats Next?

In the next chapter/post, I will cover all the steps that are required to set up a local environment and run the initial application.

Short video tutorial

Summary

This Angular Getting Started post covered the overview of the course. Also, we looked at what is Angular, the JavaScript framework, and why Angular framework is. I hope you enjoyed it and are excited to learn the next module.

The post Angular Getting Started | Course overview and Introduction | Part 1 appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/angular-getting-started-course-overview-and-introduction-part-1/feed/ 0 989
Google place autocomplete integration with Angular 11 using the reactive form https://karthiktechblog.com/angular/google-place-autocomplete-integration-with-angular-11-using-the-reactive-form/?utm_source=rss&utm_medium=rss&utm_campaign=google-place-autocomplete-integration-with-angular-11-using-the-reactive-form https://karthiktechblog.com/angular/google-place-autocomplete-integration-with-angular-11-using-the-reactive-form/#comments Tue, 21 Sep 2021 10:04:47 +0000 https://karthiktechblog.com/?p=812 Google place autocomplete integration with Angular 11 is now easy to build and use. Getting addresses from customers is so common these days in any application. Verifying the received address is going to be a challenge. We can overcome this by using Google place autocomplete to get the suggested address and even more accurate address. […]

The post Google place autocomplete integration with Angular 11 using the reactive form appeared first on KarthikTechBlog.

]]>
Google place autocomplete integration with Angular 11 is now easy to build and use.

Getting addresses from customers is so common these days in any application. Verifying the received address is going to be a challenge. We can overcome this by using Google place autocomplete to get the suggested address and even more accurate address.

What is Google Place Autocomplete

According to Google documentation, The Place Autocomplete service is a web service that returns place predictions in response to an HTTP request.

The request specifies a textual search string and optional geographic bounds. The service can be used to provide autocomplete functionality for text-based geographic searches, by returning places such as businesses, addresses, and points of interest as user types.

To know more about the documentation, visit the place autocomplete

Build Address component using Place Autocomplete

In this example, I will create the following to build the final address component that uses the Google Place Autocomplete feature.

  1. A service named “google-address” provides methods to exact the google data.
  2. Address component that will be used to collect address from the user or autoselect suggested address from autocomplete. This is built using Reactive Forms.

Steps to build Place Autocomplete feature.

Step 1:

Before you start using the Places API, you need a project with a billing account and the Places API enabled.

once you have the Key, use the below script in your HTML to load the library from google.


<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=<yourkey>"></script>

Step 2:

Install package “@types/googlemaps” of version ^3.43.3. Your package will look like “@types/googlemaps”: “^3.43.3”.

In the below code, you can specify what type of addresses you are allowing the user to find in the search result. I have not specified any type of address type so I get to see the address using Entity name, direct address as well.


const autocomplete = new google.maps.places.Autocomplete(
      this.addresstext.nativeElement,
      {
        componentRestrictions: { country: 'US' },
        types: [this.addressType]  // 'establishment' / 'address' / 'geocode' // we are checking all types
      }
    );

Address Component HTML

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item"><a href="#">Home</a></li>
        <li class="breadcrumb-item" aria-current="page">Google Address</li>
        <li class="breadcrumb-item active" aria-current="page"> Address type: <b>{{addressType}}</b></li>
    </ol>
</nav>

<div class="container">
    <h1> Google Places Autocomplete </h1>
    <form [formGroup]="addressForm">
        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label for="addressLine1">Street line 1</label>
                    <input type="text" #addresstext required="required" formControlName="addressLine1"
                        autocomplete="off" class="form-control" id="addressLine1" aria-describedby="emailHelp"
                        placeholder="Enter street line 1">
                    <small id="addressLine1" class="form-text text-muted">Start typing address for auto complete</small>
                </div>
                <div class="form-group">
                    <label for="city">City</label>
                    <input type="text" class="form-control" id="addressLine2" aria-describedby="city"
                        formControlName="city" placeholder="Enter city">
                </div>
                <div class="form-group">
                    <label for="city">State</label>
                    <select class="form-control" formControlName="state" id="state">
                        <option value="">- - Select - -</option>
                        <option value="AL">Alabama</option>
                        <option value="NJ">New Jersey</option>
                        <option value="NY">New York</option>
                    </select>
                </div>
            </div>
            <div class="col-md-6">
                <div class="form-group">
                    <label for="addressLine2">Street line 2</label>
                    <input type="text" class="form-control" id="addressLine2" aria-describedby="addressLine2"
                        formControlName="addressLine2" placeholder="Enter street line 2">
                </div>
                <br>
                <div class="form-group">
                    <label for="city">Postal Code</label>
                    <input type="text" class="form-control" id="postalCode" aria-describedby="postalCode"
                        formControlName="postalCode" placeholder="Enter postal code">
                </div>
                <div class="form-group">
                    <label for="city">Country</label>
                    <select class="form-control" formControlName="country" id="country">
                        <option value="">- - Select - -</option>
                        <option value="US">United States of America</option>
                    </select>
                </div>
            </div>
        </div>
    </form>

    <div *ngIf="showDetails">
        <div class="card">    
         
            <div class="card-body">
                <div class="panel-heading"><h2>Google Response Details</h2></div>   <br>
                <h5>Formatted Address</h5>
                <p>
                    {{formattedAddress}}
                </p>
                <br>
                <h5>Google entire response object</h5>
                <pre>
                    {{place | json}}
                </pre>
            </div>

        </div>

    </div>
</div>

Address Component TS file

In this component, to retrieve the specific address data, I have built a custom service that exacts the information.

import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { GoogleAddress } from '../model/address';
import { GoogleAddressService } from '../service/google-address.service';

@Component({
  selector: 'app-address',
  templateUrl: './address.component.html',
  styleUrls: ['./address.component.scss']
})
export class AddressComponent implements OnInit {
  showDetails = false;
  @Input() addressType: string;
  place!: object;
  @ViewChild('addresstext') addresstext: any;
  
  establishmentAddress: Object;

  formattedAddress: string;
  formattedEstablishmentAddress: string;

  addressForm!: FormGroup;
  googleAddress!: GoogleAddress;

  constructor(private googleAddressService: GoogleAddressService,
    private formBuilder: FormBuilder) { }

  ngOnInit(): void {
    this.initializeAddressForm();
  }

  initializeAddressForm() {
    const initialAddress : GoogleAddress =  {
      addressLine1: '', addressLine2: '', city: '' , state: '', country: '', postalCode: ''
    };
    this.googleAddress = initialAddress;

    this.addressForm = this.formBuilder.group({
      addressLine1: new FormControl(this.googleAddress.addressLine1, [Validators.required,
      Validators.maxLength(200)]),
      addressLine2: new FormControl(this.googleAddress.addressLine2),
      city: new FormControl(this.googleAddress.city, [Validators.required,
      Validators.maxLength(100)]),
      state: new FormControl(this.googleAddress?.state, [Validators.required,
      Validators.maxLength(50)]),
      postalCode: new FormControl(this.googleAddress.postalCode, [Validators.required,
      Validators.maxLength(15)]),
      country: new FormControl(this.googleAddress?.country, [Validators.required,
      Validators.maxLength(50)])
    });
  }

  ngAfterViewInit() {
    this.getPlaceAutocomplete();
  }

  private getPlaceAutocomplete() {
    const autocomplete = new google.maps.places.Autocomplete(
      this.addresstext.nativeElement,
      {
        componentRestrictions: { country: 'US' },
        types: [this.addressType]  // 'establishment' / 'address' / 'geocode' // we are checking all types
      }
    );
    google.maps.event.addListener(autocomplete, 'place_changed', () => {
      this.place = autocomplete.getPlace();
      this.formattedAddress = this.googleAddressService.getFormattedAddress(this.place);
      this.patchGoogleAddress();
      this.showDetails = true;
    });
  }

  patchGoogleAddress() {
    const streetNo = this.googleAddressService.getStreetNumber(this.place);
    const street = this.googleAddressService.getStreet(this.place);
    let googleAddress: GoogleAddress = {
      addressLine1: `${streetNo === undefined ? '' : streetNo} ${street === undefined ? '' : street
        }`,
      addressLine2: '',
      postalCode: this.googleAddressService.getPostCode(this.place),
      city: this.googleAddressService.getLocality(this.place),
      state: this.googleAddressService.getState(this.place),
      country: this.googleAddressService.getCountryShort(this.place),
    };
    this.addressForm.markAllAsTouched();
    this.patchAddress(googleAddress);
  }

  patchAddress(address: GoogleAddress) {
    if (this.addressForm !== undefined) {
      this.addressForm
        .get('addressLine1')!
        .patchValue(address.addressLine1);
      this.addressForm
        .get('addressLine2')!
        .patchValue(address.addressLine2);
      this.addressForm.get('postalCode')!.patchValue(address.postalCode);
      this.addressForm.get('city')!.patchValue(address.city);
      this.addressForm.get('state')!.patchValue(address.state);
      this.addressForm.get('country')!.patchValue(address.country);
    }
  }
}

Please note that I have filled the states and Country with few values. you can fill the dropdown with all possible states and countries.

Step 3:

Building custom google address service for ease of use.

GoogleAddressService

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

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

  constructor() { }

  getPlaceId(place: object){
    return place['place_id'];
}

getFormattedAddress(place: object){
  return place['formatted_address'];
}

getAddrComponent(place, componentTemplate) {
  let result;

  for (let i = 0; i < place.address_components.length; i++) {
    const addressType = place.address_components[i].types[0];
    if (componentTemplate[addressType]) {
      result = place.address_components[i][componentTemplate[addressType]];        
      return result;
    }
  }
  return;
}

getStreetNumber(place) {
  const COMPONENT_TEMPLATE = { street_number: 'short_name' },
    streetNumber = this.getAddrComponent(place, COMPONENT_TEMPLATE);

  return streetNumber===undefined?'':streetNumber;
}

getStreet(place) {
  const COMPONENT_TEMPLATE = { route: 'long_name' },
    street = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return street;
}

getLocality(place) {
  const COMPONENT_TEMPLATE = { locality: 'long_name' },
    city = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return city;
}

getState(place) {
  const COMPONENT_TEMPLATE = { administrative_area_level_1: 'short_name' },
    state = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return state;
}

getDistrict(place) {
  const COMPONENT_TEMPLATE = { administrative_area_level_2: 'short_name' },
    state = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return state;
}

getCountryShort(place) {
  const COMPONENT_TEMPLATE = { country: 'short_name' },
    countryShort = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return countryShort;
}

getCountry(place:any) {
  const COMPONENT_TEMPLATE = { country: 'long_name' },
    country = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return country;
}

getPostCode(place) {
  const COMPONENT_TEMPLATE = { postal_code: 'long_name' },
    postCode = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return postCode;
}

getPhone(place) {
  const COMPONENT_TEMPLATE = { formatted_phone_number: 'formatted_phone_number' },
    phone = this.getAddrComponent(place, COMPONENT_TEMPLATE);
  return phone;
}
}

The formatted address property is the address that you will see in google suggestions on the dropdown list.

Google Place Autocomplete Demo

Complete Application Code

You may download the entire working code from GitHub repository

Tips and Troubleshooting

After placing all the above code if the auto-complete feature is not working then you need to verify the below settings and fix them in order for it to work.

  1. go to tsconfig.json file and add ""node_modules/@types"  under "typeRoots"
tsconfig file for google place autocomplete

Conclusion

In this post, you learned how to use Google place autocomplete integration with Angular 11 and more tips to make it work with the latest Angular and typescript code.

The post Google place autocomplete integration with Angular 11 using the reactive form appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/google-place-autocomplete-integration-with-angular-11-using-the-reactive-form/feed/ 2 812
Implementing ISO 8601 date time format in Angular https://karthiktechblog.com/angular/implementing-iso-8601-date-time-format-in-angular/?utm_source=rss&utm_medium=rss&utm_campaign=implementing-iso-8601-date-time-format-in-angular https://karthiktechblog.com/angular/implementing-iso-8601-date-time-format-in-angular/#respond Sun, 14 Jun 2020 02:50:30 +0000 https://karthiktechblog.com/?p=524 In this post, I will show you how to Implement ISO 8601 date time format in Angular. Formatting a date-time in a client-side application like Angular is always a challenge. Are you looking for an unambiguous calendar-and-clock format that is internationally understood? It’s time for ISO 8601. From ISO.ORG Read more about ISO 8601 DATE AND TIME […]

The post Implementing ISO 8601 date time format in Angular appeared first on KarthikTechBlog.

]]>
In this post, I will show you how to Implement ISO 8601 date time format in Angular. Formatting a date-time in a client-side application like Angular is always a challenge.

Are you looking for an unambiguous calendar-and-clock format that is internationally understood? It’s time for ISO 8601.

From ISO.ORG

Read more about ISO 8601 DATE AND TIME FORMAT

What benefit do I get for ISO 8601?

ISO 8601 can be used by anyone who wants to use a standardized way of presenting:

  • Date
  • Time of day
  • Coordinated Universal Time (UTC)
  • Local time with offset to UTC
  • Date and time
  • Time intervals
  • Recurring time intervals

ISO 8601 date-time format Implementation

Let’s create a generic HashTable to use as Key.

export interface HashTable {
  [key: string]: T;
}

Now, Let’s create a Service for DateFormat as shown below

import { Injectable } from '@angular/core';
import { HashTable } from './hash-table';

type FormatFunc = (date: Date) => string;
@Injectable({
  providedIn: 'root'
})
export class DateFormat {
  formattingTokenFunc: HashTable = {};

  private formattingTokens = /(HH?|HH?|hh?|mm?|ss?|MM?|dd?|yy?y?y?|.)/g;

  constructor() {
    // add years function
    const getYearFunc = (date: Date) => date.getFullYear().toString();

    // Year, no leading zero (e.g. 2015 would be 15)
    this.addFormatToken('y', 0, (date: Date) =>
      (date.getFullYear() % 100).toString()
    );
    this.addFormatToken('yyy', 0, getYearFunc);
    this.addFormatToken('yyyy', 0, getYearFunc);
    // Year, leading zero (e.g. 2015 would be 015)
    this.addFormatToken('yy', 3, (date: Date) =>
      (date.getFullYear() % 100).toString()
    );

    // add months function
    const getMonthFunc = (date: Date) => (date.getMonth() + 1).toString();

    this.addFormatToken('M', 0, getMonthFunc);
    this.addFormatToken('MM', 2, getMonthFunc);

    // add day function
    const getDayFunc = (date: Date) => date.getDate().toString();

    this.addFormatToken('d', 0, getDayFunc);
    this.addFormatToken('dd', 2, getDayFunc);

    // add hours function
    const get12HrFunc = (date: Date) => (date.getHours() % 12).toString();

    // 12-hour clock, with a leading 0 eg (e.g. 06)
    this.addFormatToken('hh', 2, get12HrFunc);
    // 12-hour clock hour
    this.addFormatToken('h', 0, get12HrFunc);

    const get24HrFunc = (date: Date) => date.getHours().toString();

    this.addFormatToken('HH', 2, get24HrFunc);
    this.addFormatToken('H', 0, get24HrFunc);

    // add minute function
    const getMinFunc = (date: Date) => date.getMinutes().toString();
    this.addFormatToken('m', 0, getMinFunc);
    // Minutes with a leading zero
    this.addFormatToken('mm', 2, getMinFunc);

    // add seconds function
    const getSecFunc = (date: Date) => date.getSeconds().toString();
    this.addFormatToken('s', 0, getSecFunc);
    this.addFormatToken('ss', 2, getSecFunc);
  }

  formatToISO8601Date(date: Date | string): string {
    return this.format(date, 'yyyy-MM-dd');
  }

  format(date: Date | string, format: string): string {
    const finalDate = date instanceof Date ? date : new Date(date);

    const matches = format.match(this.formattingTokens);
    let result = '';

    matches.forEach(match => {
      // const hasFunc = this.formattingTokenFunc.hasOwnProperty('match');
      const formatFunc = this.formattingTokenFunc[match];

      result += formatFunc ? formatFunc(finalDate) : match;
    });

    return result;
  }

  prefixZero(length: number, input: string): string {
    return `${Math.pow(10, length)}${input}`.slice(-1 * length);
  }

  prefixZeroFunc(length: number, formatFunc: FormatFunc): FormatFunc {
    return (c: Date) => this.prefixZero(length, formatFunc(c));
  }

  private addFormatToken(
    token: string,
    addZeroesLength: number,
    // formatFunc: ((date: Date) => string)
    formatFunc: FormatFunc
  ): void {
    this.formattingTokenFunc[token] =
      addZeroesLength > 0
        ? this.prefixZeroFunc(addZeroesLength, formatFunc)
        : formatFunc;
  }
}
Implementing ISO 8601 date time format in Angular
Implementing ISO 8601 date time format in Angular

By Injecting this service at root level, any component or service in the Angular application can ask for it using DI and then make use of it.

How to consume DateFormat service

Let’s say you have a variable for date and you need to initiate the date in ISO 8601 format.

@Component({
  selector: 'app-dateformat-example',
  templateUrl: './dateformat-example.component.html',
  styleUrls: ['./dateformat-example.component.css']
})
export class DateFormatExampleComponent implements OnInit {
effectiveDate: any;
constructor(
  private dateFormat: DateFormat) { }

  ngOnInit() {
    this.effectiveDate = this.dateFormat.formatToISO8601Date(new Date());
  }
}

Related Post

Conclusion

In this post, I showed Implementing ISO 8601 date time format in Angular. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post Implementing ISO 8601 date time format in Angular appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/implementing-iso-8601-date-time-format-in-angular/feed/ 0 524
How to reset the selected file with input tag file type in Angular 9 https://karthiktechblog.com/angular/how-to-reset-the-selected-the-file-with-input-tag-file-type-in-angular-9/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-reset-the-selected-the-file-with-input-tag-file-type-in-angular-9 https://karthiktechblog.com/angular/how-to-reset-the-selected-the-file-with-input-tag-file-type-in-angular-9/#respond Sun, 05 Apr 2020 22:46:05 +0000 https://karthiktechblog.com/?p=459 In this short post, I will show how to reset the selected file with the input tag file type in Angular 9. The usage of file input in HTML is more common. It is always good to reset or clear the selected files after a successful process of the file on the server-side. Input File: […]

The post How to reset the selected file with input tag file type in Angular 9 appeared first on KarthikTechBlog.

]]>
In this short post, I will show how to reset the selected file with the input tag file type in Angular 9. The usage of file input in HTML is more common. It is always good to reset or clear the selected files after a successful process of the file on the server-side.

Input File: HTML Code for Angular 9

<form [formGroup]="form">
  <div class="form-group">
    <label for="file"></label>
    <input type="file" #fileInput formControlName="fileContact" id="file" required
      (change)="handleFileInput($event.target.files)">
    <button type="button" class="btn btn-info" (click)="clearSelection()">Clear</button>
  </div>
</form>

Now by using the template variable “fileInput“, we can access the HTML element to clear the files.

How to reset the selected file with input tag file type in Angular 9
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';

 @ViewChild('fileInput', {static: false})
  myFileInput: ElementRef;

Import ViewChild and ElementRef to support this functionality.

Using this template variable, clear the files.

this.myInputVariable.nativeElement.value = '';

Related Post

Looking for a complete example? read this post How to upload a file from Angular 9 with .NET Core Web API

Reference

Read more on Template syntax

Conclusion

In this post, I showed how to reset the selected file with the input tag file type in Angular 9. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post How to reset the selected file with input tag file type in Angular 9 appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/how-to-reset-the-selected-the-file-with-input-tag-file-type-in-angular-9/feed/ 0 459
How to upload a file from Angular 9 with .NET Core Web API https://karthiktechblog.com/angular/how-to-upload-a-file-from-angular-9-with-net-core-web-api/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-upload-a-file-from-angular-9-with-net-core-web-api https://karthiktechblog.com/angular/how-to-upload-a-file-from-angular-9-with-net-core-web-api/#comments Sun, 05 Apr 2020 16:29:57 +0000 https://karthiktechblog.com/?p=451 In this post, I will show how to upload a file from Angular 9 with .NET Core. Uploading a file is the process of uploading a file from the user’s system to a hosted web application server. You may choose to store the file in the web server’s local disc or in the database. It […]

The post How to upload a file from Angular 9 with .NET Core Web API appeared first on KarthikTechBlog.

]]>
In this post, I will show how to upload a file from Angular 9 with .NET Core.

Uploading a file is the process of uploading a file from the user’s system to a hosted web application server. You may choose to store the file in the web server’s local disc or in the database.

It is easy to upload one or more files from Angular 9 with .NET Core 2.2, 3.1, or above versions.

In this post, I will show what code is needed in the Angular component and service to upload a file to the server-side using .NET Core 3.1. I will also cover some basic client-side validation from Angular 9.

Upload a file from Angular

Video Demo

Service

import { HttpClient } from '@angular/common/http';
import { CONFIG } from 'src/app/config';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class UploadService {
    private apiUrl: string;

    constructor(private http: HttpClient) {
        this.apiUrl = CONFIG.coreAPIUrl;
    }

    public uploadFile(file: FormData): Observable {
        const url = `${this.apiUrl}/${CONFIG.apiEndpoints.encode.fileToBase64}`;
        return this.http.post(url, file);
    }
}

In this service, we have a HttpPost method in which we post the file to the server to upload the local file. This is done using FormData as a parameter.

How to upload a file from Angular 9 with .NET Core

Component

import { Component, OnInit, ChangeDetectionStrategy, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { LoadingService } from '@control-tower/lib';
import { Subject } from 'rxjs';
import { FileContentModel } from '../model/file-content-model';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-upload',
  templateUrl: './upload.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [LoadingService]
})
export class UploadComponent implements OnInit {

  @ViewChild('fileInput', {static: false})
  myFileInput: ElementRef;
  public fileContentModel: FileContentModel;
  public form: FormGroup;
  public errors: string[] = [];
  private destroy: Subject = new Subject();

  constructor(
    private uploadService: UploadService
  ) { }

  public ngOnInit() {
    this.form = this.buildForm();
  }

  private buildForm(): FormGroup {
    return new FormGroup({
      fileContact: new FormControl('', [Validators.required])
    });
  }

  public Submit(files: File[]): void {
    this.handleFileInput(files);
  }

  public handleFileInput(files: File[]): void {

    if (this.form.valid && files[0].name.split('.').pop() === 'excel') {
      const formData = new FormData();

      Array.from(files).forEach(f => formData.append('file', f));

      this.uploadService.uploadPdfToGetBase64(formData).subscribe(
        (res: any) => {
          this.myFileInput.nativeElement.value = '';
        },
        (errorRes: HttpErrorResponse) => {
          alert('error occured');
          this.form.reset();
          this.myFileInput.nativeElement.value = '';
        }
      );
    } else {
      alert('Invalid file selected. Only excel is allowed');
    }
  }

}

Explanation

In this component, we consume UploadService in the constructor and then invoke the upload method to send the file to the server.

We create an instance of FormData and append the files to it as KeyValue pair.

Once the response is received, we could display success message or in case of error, we display appropriate error message.

In this example, I have applied a validation to check only excel files can be selected. Any other files selected will show an error message to the user.

Let me show what HTML will look like for file upload.

<form [formgroup]="form">
  <div class="form-group">
    <label for="file"></label>
    <input type="file" #fileinput="" formcontrolname="fileContact" id="file" required="" (change)="handleFileInput($event.target.files)">
    <button type="button" class="btn btn-info" (click)="clearSelection()">Clear</button>
  </div>
</form>

I have separate posts to set up upload functionality with .NET Web API and .NET Core versions. Both do the same functionality however, the way you read the files is a little different.

Reference Posts:

Conclusion

In this post, I showed how to upload a file from Angular 9 with .NET Core. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post How to upload a file from Angular 9 with .NET Core Web API appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/how-to-upload-a-file-from-angular-9-with-net-core-web-api/feed/ 2 451
How To Fix Your Angular App To Make it work in IE11 https://karthiktechblog.com/angular/how-to-fix-your-angular-app-to-make-it-work-in-ie11/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-fix-your-angular-app-to-make-it-work-in-ie11 https://karthiktechblog.com/angular/how-to-fix-your-angular-app-to-make-it-work-in-ie11/#comments Wed, 04 Mar 2020 18:42:58 +0000 https://karthiktechblog.com/?p=412 Introduction In this short post, I will show How To Fix Your Angular App To Make it work in IE11. In Angular CLI version 8 and higher, applications are built using differential loading, a strategy where the CLI builds two separate bundles as part of your deployed application. The first bundle contains modern ES2015 syntax, takes […]

The post How To Fix Your Angular App To Make it work in IE11 appeared first on KarthikTechBlog.

]]>
Introduction

In this short post, I will show How To Fix Your Angular App To Make it work in IE11.

In Angular CLI version 8 and higher, applications are built using differential loading, a strategy where the CLI builds two separate bundles as part of your deployed application.

  • The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size.
  • The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers

Problem Statement

After Angular version 2, many things have changed. You app with version 2 or 4 might have worked in IE and when you upgraded your app to 6 or 8 then the IE stopped working. You might have come across many website stating this is because of Polyfills. That’s not the case always

Polyfills

Angular is built on the latest standards of the web platform. Targeting such a wide range of browsers is challenging because they do not support all features of modern browsers. You compensate by loading polyfill scripts (“polyfills”) for the browsers that you must support.

Angular.IO

Read about browser-support

So for specific use case, Polyfill might work. However, for supporting IE, you need two change to your configuration. Let’s see what are those to make this IE work both when debugging and after deploying to production.

Solution

Add a property  "es5BrowserSupport": true in angular.json file

How To Fix Your Angular App To Make it work in IE11
IE 11 Support

Now, change your target as "es5" in tsconfig.json file

support IE11 for angular app
IE 11 support

Also see other common issues encountered by developers.

Entity Framework Core dbcontextoptionsbuilder does not contain a definition for usesqlserver – Solved

Conclusion

Thanks for reading this piece. As you can see, to support IE 11, you need to add es5BrowserSupport property in angular.json file and change the target as es5 in tsconfig.json file that solved the problem. Let me know in the comments if you have questions.

The post How To Fix Your Angular App To Make it work in IE11 appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/angular/how-to-fix-your-angular-app-to-make-it-work-in-ie11/feed/ 1 412