Template Variable to Interact with Child Components in Angular 2+

I have already discussed in my last couple of blogs to interact Components using @Input and @Output. Here I am going to explain about Template Variable to interact with Child Components. By using this Template reference variable you can access public properties and methods of a child component and also to bind data to a child component.
Template Reference Variable allow you to specify a variable name on a component and you can access any public property or methods on that component using that variable.

In order to demonstrate I have a product card component which is my child component placed inside the  ProductListComponent(parent component) to list some products. You can see I have added a template reference variable named #productReference on this child component

So over here in our ProductCardComponent will just a create a method and property to access from the ProductListComponent

Now you can access this property and method from the ProductListComponent

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 feature in order to implement the need of $compile in Angular 1.0

WidgetHostDirective
In order to load a dynamic component you have to create a directive that you can apply to ng-template , which will helps to place 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 is just a place holder component to load the dynamic component.This component accepts an input(contains what component you want to load at runtime)  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.html

WidgetComponentService
This is a simple angular service factory to register the component we want to load at runtime

ImageTextWidgetComponent(Component we registered inside the factory loads dynamically )
import { Component, OnInit, Input, ReflectiveInjector, Injector } from '@angular/core';
@Component({
selector: 'imagetextwidget',
templateUrl: 'app/templates/ImageTextWidget.html'
})

export class ImageTextWidgetComponent implements OnInit {
@Input() data: any;
constructor() {

}
ngOnInit() {

}
}

Entry Component

Finally to ensure that the compiler still generates a factory, add dynamically loaded components to the NgModule’s entryComponents array. You can add this in to your app module

Communicating with child components from parent component in Angular 2+

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.