What are tree shakeable providers?

When we register providers in @NgModule(), angular internally includes all those related classes in the final bundle, irrespective of their actual use in the application. To overcome this, it is recommended to use @Injectable() decorator when creating a service as below:

@Injectable({
  providedIn: 'root'
})
export class MyShakeableService {
  // some logic
}

This enables the Angular to inspect which services are actually being used in the application and 'exclude' unused service classes from the final bundle - there by reducing the bundle size. These kind of providers are called as 'tree shakeable'. This was introduced in Angular 6.

What are Pure Pipes and Impure Pipes?

Pipes by default are "Pure" - they can't detect changes when a value of the primitive type or the reference of the complex type changes. Example: when an array gets a new value inserted but the Pipe applied on that array during view binding can't detect its change.

To Solve this, we can mark the pipe as "Impure" - which forces the Pipe to detect change and update the view each time the dataset changes.

<span>{{ myData | doPipe }}</span>

@Pipe({name:'doPipe', pure: false})
export class DoPipe implements PipeTransform {
  /// pipe code
}

What are Async Pipes?

Async Pipes help transforming data coming from an Observable and resolve into desired dataset. It also takes care of the Subscription and Unsubscription of the Observable.

this.http.get(url).pipe((map((res) => {
    // some handling of the response here
    return res;
});

What are Hot Observables and Cold Observables?

  • Cold Observables are observables where data is produced inside the Observable. It can be treated as a unicast.
const obs$ = new Obserable((observer) => {
    observer.next(Math.random());
});
obs$.subscribe((data) => console.log(data)); // prints different value
obs$.subscribe((data) => console.log(data)); // prints different value
  • Hot Observables are observables where data is produced outside the Observable. It can be treated as a multicast.
const data = 5;
const obs$ = new Obserable((observer) => {
    observer.next(data);
});
obs$.subscribe((data) => console.log(data)); // prints 5
obs$.subscribe((data) => console.log(data)); // prints 5

What is the difference between a Component and a Directive?

Directive:

  • Directives help in modifying the behavior of an existing DOM element or adding new behavior to the DOM.
  • Directives are created by using the @Directive() decorator, and can be structural (which modify the DOM structure - ngIf, ngFor or ngSwitchCase) or behavioral (add new behavior to the existing DOM elements - ngStyle, ngClass or ngModel)
  • Directives don't possess their own View

Component:

  • Components are considered as a special branch of directives which can control a small portion of the View
  • Components are associated with an encapsulated View Template, Style and the View Logic (class) parts
  • These are created by using the @Component() decorator

What are the different Guards present in Angular?

Guards in Angular help us in controlling access to certain routes of our application, unless a criteria is matched. Angular provides the following interfaces for us to implement and create Guards for required use cases:

  1. CanActivate - navigation to an individual route corresponding to a component
  2. CanActivateChild - navigation to all the child routes and components of a specific route
  3. CanDeactivate - guards the exit from a component route and allows on a matching criteria
  4. CanLoad - lets the application lazyload all the routes of a module only if a condition is met
  5. Resolve - helps in prefetching all the component data before the route is activated.

How do you create an Interceptor? It is a service or class?

We can create by implementing the HttpInterceptor interface from @angular/common/http package. We register it to be attached to the HTTP request pipeline by adding it to the providers array in the NgModule. We can also enable DI into the interceptor by registering it as a service.

@Injectable({
    providedIn: "root"
})
export class PostsInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler)
      : Observable<HttpEvent<any>> {
        // fiddling happens here
        return next.handle(req);
    }
}
// NgModule
providers: [{
       provide: HTTP_INTERCEPTORS,
       useClass: PostsInterceptor,
       multi: true
}]

How can you pass a header to all the http requests created from an angular app?

We can read an outgoing HTTP request from an angular application and modify it to always pass a particular header, such as an Authorization header carrying a token to the API by registering a HttpInterceptor. We can also make use of it to read a response before being relayed to the actual source of request. It thereby provides use cases such as Logging, Exception Handling and Headers etc.

@Injectable({
    providedIn: "root"
})
export class PostsInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler)
          : Observable<HttpEvent<any>> {
        // req object can be modified here
        return next.handle(req);
    }
}