Load Components Dynamically at runtime in Angular 4

Angular Version I have used – 4.2.0
Here I am going to explain how to load dynamic components at runtime. By using angular ComponentFactoryResolver you can load components dynamically. In the below example I am loading a Image widgets in to tile(nothing but a container div to load the widget at runtime). You can use this to in order to implement the need of $compile in Angular 1.0

WidgetHostDirective
In order to load a dynamic component you need a directive that you can apply to ng-template which will helps to load the components at run time. This directive injects ViewContainerRef to gain access to the view container of the element that will host the dynamically added component.

import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[widget-host]',
})
export class DashboardTileWidgetHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}

DashboardTileComponent
This component accepts an input which is coming from a parent components or you can load from your service based on your implementation. This component is doing the major role to resolve the components at runtime. In this method you can also see a method named renderComponent() which ultimately loads the component name from a service and resolve with ComponentFactoryResolver and finally setting data to the dynamic component.
import { Component, Input, OnInit, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { DashboardTileWidgetHostDirective } from './DashbardWidgetHost.Directive';
import { TileModel } from './Tile.Model';
import { WidgetComponentService } from "./WidgetComponent.Service";
@Component({
selector: 'dashboard-tile',
templateUrl: 'app/tile/DashboardTile.Template.html'
})
export class DashboardTileComponent implements OnInit {
@Input() tile: any;
@ViewChild(DashboardTileWidgetHostDirective) widgetHost: DashboardTileWidgetHostDirective;
constructor(private _componentFactoryResolver: ComponentFactoryResolver,private widgetComponentService:WidgetComponentService) {

}
ngOnInit() {

}
ngAfterViewInit() {
this.renderComponents();
}
renderComponents() {
let component=this.widgetComponentService.getComponent(this.tile.componentName);
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
let viewContainerRef = this.widgetHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(componentRef.instance).data = this.tile;

}
}
export interface TileModel {
data: any;
}

You can see I have applied the directive we have created before to the ng-template
DashboardTileComponent Template

WidgetComponentService
This is a simple angular service which just the component name that we want to load at runtime

Entry Component
To ensure that the compiler still generates a factory, add dynamically loaded components to the NgModule’s entryComponents array

Communicating with parent component from child component in Angular Js2

In my last blog I have explained about @Input decorator to pass data from parent component to the child component. @Output is on other hand used in response to some event within a child component to receive some information for the parent component through some events. If you are not read my previous blog , I would suggest you to read the same. I have used the same example here also.

Child Component
Let’s talk about the child component first. You can see I have a simple method named productCardClick() which I am calling when clicking on the button. It’s pretty straight forward.

Modifying the child component
Next I am going to pass some data to the parent through the same productCardClick() method in the child component. In order to do that first you have to add a new property of type EventEmitter and emit the data you want to pass in to the parent component through this property like below .

Parent Component
Let’s go the parent component named ProductListComponent


In the parent component (ProductListComponent) you can see I have receiver method named onProductCardClickHandled(data:any) with a parameter to receive the data from the child component and I am calling this receiver method with a parameter via the @Output decorated property onProductCardClick inside the child component. Now when you click the button you will receive the child component data in to the parent component

Communicating with child components from parent component in Angular Js2

Breaking our application in to multiple components makes our application more organized and maintainable. Here I am going to explain how to pass data from parent component to child component.

Parent Component
Here is our ProductListComponent , which is the parent component with a productObject declared which I am going to pass in to the child component.

This is my productList html for displaying the product object. You can see I am calling the product-card component(Child Component) from this productListComponent

Child Component

Child Component template

In this component I have declared a variable named product decorated with @Input , which tell to the child component that , you will get an input product from the parent component(ProductListComponent). For passing the input data from the parent component to the child component you have to add an attribute match with property decorated with the @Input inside a square bracket like below and the value here I am passing will be the productObject from the ProductListComponent

Set HTTP Cache Expiration in Angular JS and Typescript

Create an Interceptor for every service calls

angular.module('app').factory("cacheInterceptor", ["$cacheFactory", function ($cacheFactory) {
 var httpTtlCache = {};
 return {
 request: function (config) {
 var expirationTime;
 if (config.expiration) {
 expirationTime = config.expiration;
 delete config.expiration;
 if (new Date().getTime() - (httpTtlCache[config.url] || 0) > expirationTime) {
 $cacheFactory.get("$http").remove(config.url);
 httpTtlCache[config.url] = new Date().getTime();
 }
 }
 return config;
 }
 };
}]);

Push the interceptor through config

angular.module('app', []).config(['$httpProvider', function ($httpProvider) {
 $httpProvider.interceptors.push('cacheInterceptor');
}]);

Pass the expiration when you call your httpservice

  var expirationTime = 60 * 60 * 1000;
            $http.get(url, { expiration: expirationTime,cache:true }).then(function (response) {
               
            });

Transclusion in Angular js

The best way of think about transclusion is a Picture Frame.A picture frame has its own design and
a space for adding the picture.We can decide what picture will go inside of it.
Picture1
When it comes to angular we have some kind of controller with its scope and inside of that we will place a directive that supports transclusion. This directive will have it’s own display and functionality . In non-transluded directive, content inside the directive is decided by the directive itself but with transclusion,just like a picture frame,we can decide what will be inside the directive.

<body ng-controller=”appController”>
<my-frame>
<span>My Frame content</span>
</my-frame>
</body>

Directive Template

<body ng-controller=”appController”>
<my-frame>
<span>My Frame content</span>
</my-frame>
</body>

Directive
angular.module("app").directive('myFrame', function () {
return {
restrict: 'E',
templateUrl:"frame.html",
controller:function($scope){
$scope.hidden=false;
$scope.close=function(){
$scope.hidden=true;
}
},
transclude:true;
}
});

Source Code : https://plnkr.co/edit/Cnoa7E?p=preview

Custom Ajax service calls using $http in Angular Js and Typescript

In this article i am going to create a custom service for making Ajax request using Angular JS with Typescript implementation.
I have created a custom service named HttpService and abstracted all the HTTP API’s using angular $http service. You can reuse this custom service for making Ajax calls.

module App.Services {
export interface IHttpService {
get(url: string, config?: ng.IRequestShortcutConfig): ng.IPromise;
post(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise;
put(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise;
delete(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise;
}
}

module App.Services {
"use strict";
class HttpService implements IHttpService {
private $http: ng.IHttpService;
private $q: ng.IQService;
private $rootScope:ng.IRootScopeService;
static $inject = ["$http", "$q","$rootScope"];
constructor($http: ng.IHttpService, $q: ng.IQService,$rootScope:ng.IRootScopeService) {
this.$http = $http;
this.$q = $q;
this.$rootScope = $rootScope;
}
get(url: string, config?: ng.IRequestShortcutConfig): ng.IPromise {
var deferred = this.$q.defer();
this.$http.get(url, config).success(response => {
deferred.resolve(response);
}).error((data, status, headers, config) => {

deferred.reject("Error occured while processing the request");
});
return deferred.promise;
}
post(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise {
var deferred = this.$q.defer();
this.$http.post(url, data, config).success(response => {
deferred.resolve(response);
}).error((data, status, headers, config) => {

deferred.reject("Error occured while processing the request");
});
return deferred.promise;
}
put(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise {
var deferred = this.$q.defer();
this.$http.put(url, data, config).success(response => {
deferred.resolve(response);
}).error((data, status, headers, config) => {

deferred.reject("Error occured while processing the request");
});
return deferred.promise;
}
delete(url: string, data: any, config?: ng.IRequestShortcutConfig): ng.IPromise {
var deferred = this.$q.defer();
this.$http.delete(url, config).success(response => {
deferred.resolve(response);
}).error((data, status, headers, config) => {

deferred.reject("Error occured while processing the request");
});
return deferred.promise;
}
}
angular.module("App").service("HttpService", HttpService);
}

Usage

I have created one more Angular service for calling REST API’s by using our custom HttpService

module App.Services {
"use strict";
class SampleService implements ISampleService {
private httpService: App.Services.IHttpService;
static $inject = ["HttpService"];
constructor(httpService: App.Services.IHttpService) {
this.httpService = httpService;
}
getDataFromService(): ng.IPromise {
return this.httpService.get("api/Home/Get")
.then((response: ng.IHttpPromiseCallbackArg): ng.IHttpPromiseCallbackArg => {
return response;
});
}

}
angular.module("App").service("SampleService", SampleService);
}

Calling this Sample Service from a Angular Controller

module App.Controllers {
export class SampleController {
static $inject = ["SampleService"];
serviceData: App.Services.ISampleService;
message: any;
constructor(serviceData: App.Services.ISampleService) {
this.serviceData = serviceData;
this.serviceData.getDataFromService().then((serviceData: any): void=> {
this.message = serviceData;
});
}
}
angular.module("App").controller("SampleController", SampleController);
}

Ajax Loader using Angularjs

Introduction
In this article i am focus on How to implement Ajax Loader or busy Indicator using AngularJs
Custom Directive for loader
Angular Directives are markers of a DOM element. Using this you can create your own custom elements,custom events.

More about angular directives

Here i am going to create a custom attribute directive named busyindicator to show a busy loading indicator during Ajax call.


(function () {
"use strict";
angular.module("App").directive("busyindicator", busyIndicator);
function busyIndicator() {
var directive = {
restrict: "A",
link: function ($scope) {
$scope.$on("showBusyIndicator", function () {
$scope.canShow = true;
});
return $scope.$on("hideBusyIndicator", function () {
$scope.canShow = false;
});
}
};
return directive;
}
})();

If any http request is in progress , Angular JS will automatically update the anyRequestInProgress property to true on the scope object and once the request complete it will set back to false. In this directive link function i have created a angular watch function whenever if any changes in anyRequestInProgress property it will notify this method.

Apply the busyindicator directive to the html element as an attribute also the visible status property canShow to angularjs ng-show directive to hide and show the div.

 

//CSS for showing loader image in the center of a screen

#loaderdiv
{
display : none;
}
#loaderdiv.loader {
display : block;
position : fixed;
z-index: 100;
background-image : ‘loader.gif’
-ms-opacity : 0.4;
opacity : 0.4;
background-repeat : no-repeat;
background-position : center;
left : 0;
bottom : 0;
right : 0;
top : 0;
}


You no need to write any code for show & hide loader element . Our custom directive automatically handle this based on our service request.