Angular PDF Viewer Component

You may come over a requirement to view PDF within your Angular 5+ application. Building that from scratch might be a time and effort consuming task. Thanks to ng2-pdf-viewr component, it is providing the developers with a ready made component that you can import into your Angular project and start using it in very easy way.

In my case scenario, The PDF Viewer latest version (7.0.1) didn’t work and it was giving me compilation issues whenever I’m try to compile my application. So I had to use an older version in my Angular project (I used version 6.4.1). By using the 6.4.1 version, I overcome the compilation issue.

I order to use the ng2-pdf-viewer, it is basically consist of few steps:

  • Install the component to be part of your project
npm i ng2-pdf-viewer@6.4.1  --save
  • Compile your application to make sure new component will be compiled successfully
  • Add PDF Viewer module to your module class
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';

import { PdfViewerModule } from 'ng2-pdf-viewer';

@NgModule({
  imports: [BrowserModule, PdfViewerModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})

class AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);
  • Add PDF Viewer html tag to your html page and make sure the pdf URL is pointing to a valid pdf file.
import { Component } from '@angular/core';

@Component({
  selector: 'my-poc-app',
  template: `
  <pdf-viewer [src]="pdfSrc"  style="display: block;" ></pdf-viewer>
  `
})
export class MyPOCComponent {
  pdfSrc = "https://blog.smartdigitizers.com/wp-content/uploads/TestPDFFile.pdf";
}

References:

https://www.npmjs.com/package/ng2-pdf-viewer/v/6.4.1
https://www.npmjs.com/package/ng2-pdf-viewer

How to Implement Keyboard Shortcuts for your Web Application

In order to increase the user productivity and efficiency while using your web application, you might ended up implementing some sort of keyboard shortcuts. This will enable the end user to use the keyboard to do some actions or to navigate to certain pages without the need to use the mouse.

Implementing keyboard shortcuts in Angular is pretty simple thing. Basically you will need to decorate your Angular event handler method with HostListener attribute.. yes, that’s it. Here is a code sample that will show how to let the user using F10 to save the record

import { Component, HostListener } from '@angular/core';
export class AppComponent {
constructor() {
}

@HostListener('window:keydown.f10', ['$event'])
showPinned(event: KeyboardEvent) {
   event.preventDefault();
   alert('F10 pressed');
   this.save();
}
@HostListener('window:keydown.control.p', ['$event'])
pinRecord(event: KeyboardEvent) {
   event.preventDefault();
   alert('Ctrl+P pressed');
   this.saveRecordIntoHistory();
}
save() {
   //Implement Saving Logic here.
}
saveRecordIntoHistory () {
   //Implement Saving Record into History Logic here.
}
}

References

I built this article based on below references

  1. https://angular.io/api/core/HostListener 
  2. https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault 

How to loop through JSON Object using JQuery

Sometimes you get into a need where you need to loop through a JSON object while using JQuery or Angular 6 (with typescript). This is become very useful when you are not fully aware of what is the JSON object has in term of properties but you still needs to do some operations on the object properties..
So Let’s assume that you have a JSON Object called employee and you need to print the keys and values of these keys:

var employee = {
firstName: "FName",
lastName: "LName"
}

var keys = Object.keys(employee);

for (var i = 0; i < keys.length; i++) {
    console.log(keys[i]]); /*printing the key, so it will be firstName and lastName */
   console.log(employee[keys[i]]); /*printing the values; which will be FName and LName */
}

Note: This syntax is working fine with Angular 6 while using Type Script and with JQuery.

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed – JavaScript heap out of memory

Recently I faced a strange issue where I’m not being able to compile my Angular 7.0+ application because of the below error message

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::DecodeWrite
2: node_module_register
3: v8::internal::FatalProcessOutOfMemory
4: v8::internal::FatalProcessOutOfMemory
5: v8::internal::Heap::MaxHeapGrowingFactor
6: v8::internal::Factory::NewJSPromise
7: v8::internal::interpreter::operator<<
8: v8::internal::NativesCollection<0>::GetScriptsSource
9: v8::internal::NativesCollection<0>::GetScriptsSource
10: v8::internal::NativesCollection<0>::GetScriptsSource
11: 00000044D2784281

I tried to upgrade the nodeJs and Angular version for my app but with no luck. I even tried to increase the RAMs on my development PC and that didn’t solve the issue.
In order to solve this issue, you will need to adjust the default nodeJs used spaces by using the following command:

node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng build --prod --build-optimizer

Below is the original command that I was using and it was giving me the error in concern

ng build --prod --prod-optimizer

Using Bootstrap with Angular Project

Having bootstrap in any web project is becoming crucial because it is making developer’s life much easier and making the web project mobile-friendly portals. I’ve been using bootstrap for more than 8 years by now and it is becoming a main component for any project that I’m working on. In this post we will cover how to install bootstrap on Angualr project, we will be covering this step by step starting form creating a new angular project, below are steps:

  1. Open command prompt with admin permissions. To do so, on start menu search for “command prompt” and right click on it then select “Run as Administrator”
  2. Navigate to the location you want to store the project.
  3. Type the following command
ng new <Project Name>

it will be taking few minutes to download files from internet and creating the needed angular files for your project to run.

After this command completed, you will have angular project ready for run. But without bootstrap.

  1. Above command will create a new folder with your project name, navigate to it
  2. Type the following command on cmd
            npm install bootstrap jquery –save

           what above command do, is basically instructing npm to download and save bootstrap and jquery for you on the project.

  1.  Now you have bootstrap installed on your project. Let’s try to run the project, type the following command:
                  ng s -o

              sometimes, you will get the following error message

              “node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ‘;’ expected”

             To fix this issue, we need to use older version of RX to do that type the following command

                            npm install rxjs@6.0.0 –save
  1. Try run the project again.. it should be working. Next is to import the needed css files and js, Open angular.json file with any text editor file
  2. On styles tag, add the following value which is basically CSS path

               “node_modules/bootstrap/dist/css/bootstrap.min.css”

        On script tag, add the following values which is basically JS path

                 “node_modules/jquery/dist/jquery.min.js”, 

                 “node_modules/bootstrap/dist/js/bootstrap.min.js”

  1. Try to run the project using the following command
ng s -o

              you should be getting the new project open on your web browser. To test if the bootstrap is installed correctly or not, basically you can open app.component.html and add the following tag

<button class=”btn btn-primary”>test bootstrap</button>

By doing above, you will get a blue button on the main page.

Deploy Angular app to IIS Web Server

After finishing development your Angular 2+ application, I think you would be thinking of what available options to publish your app, there is plenty of options available and described on Angular website but I’m summarizing the list of actions needed to deploy  your app to IIS server.

Deploying Angular 2+ applications to IIS Web server is very easy step, it is only couple of steps.. to do so follow the below steps:

1. Build your AngularJs application for production. to do so type the following command

ng build -prod --output-path [Path]

2. Copy the generated files from step# 1 into your IIS folder.

3. Create a new website for new your application.

4. Create a new web.config file with the following contents:\

<?xml version="1.0" encoding="utf-8"?> 
<configuration>   
   <system.webServer>     
      <rewrite>       
         <rules>         
            <rule name="Angular Routes" stopProcessing="true">           
               <match url=".*" />           
               <conditions logicalGrouping="MatchAll">
                  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />            
                   <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />          
                </conditions>           
               <action type="Rewrite" url="/" />        
             </rule>      
          </rules> 
       </rewrite>   
   </system.webServer> 
</configuration> 

It is very important to make sure that your IIS web Server has the rewrite module installed on it.. the following URL has the downloadable file

https://www.iis.net/downloads/microsoft/url-rewrite

Angular Js $http Provider Interceptors

The $http Service in Angular JS allow us to communicate smoothly with back-end services. I came into a scenario where I need to monitor all http requests/responses happening using $http service. we can do that with each $http use, but I strongly believe in not copy/past and duplicate the code over and over. so I was looking into an approach to that allow me to write a function or method that will be called with each http request made.

Angular Js supporting interceptors concept for $httpProviders service. The interceptor is a service function that will be called with each call for service..In our scenario,  you can think of the interceptor as a man monitor the traffic going back and forth.

Below code is basically adding a value to http request header and test the response status if it is 600 (custom value) then do certain action.

// interceptor logic.
app.factory('httpInterceptor', function ($q) {
    return {
        request: function(config) {
            config.headers['X-MyHeaderKey'] = "MyHeaderValue";
            return config;
        },
        requestError: function(rejectReason) {    
            //Do certain actions   
            return $q.reject(rejectReason);
        },
        response: function (response) {
             //Do certain actions
             return response;
         },
        responseError: function (response) {
            if (response.status === 600) {
                //Do needed logic in case of status 600
                return $q.reject(response);
            }
             else {
                return $q.reject(response);
            }
        }
    };
});
app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('httpInterceptor');
});

$httpProviders provides 4 main types of interceptors that you can use:

1) Request Interceptor: This service method will be called when $http service send request to back-end server. in the example able we simply injected a new key/value in the http request header.

2) Response Interceptor: This service method will be called after request sent to the server and once the $http service received the response. the response will be received as a parameter to the service method.

3) RequestError Interceptor: In some cases the request can’t be sent or other interceptors reject sending the request to back-end service. In this case, this service method will be called.

4) ResponseError Interceptor: This service method will be called whenever the back-end service has failure and return error to $http service.