Personalized ngIf directive featuring an included alternate template

In Angular applications, it is a common practice to use the ngIf directive with Observables to display data and provide an else template to show a placeholder while the data is loading.

<data-view *ngIf="data$ | async as data; else progress" [items]="data">
</data-view>

<ng-template #progress>
  <mat-icon></mat-icon>
  <mat-progress></mat-progress>
</ng-template>

However, this approach involves repetitive code for the else template, async pipe, and as clause. Is there a way to eliminate this boilerplate by using a custom directive like the following:

<data-view *ngWait="data$" items="data">
</data-view>

While I understand how to combine ngIf with the async pipe, I am struggling to figure out how to incorporate the else template into a custom directive.

Answer №1

To implement the createComponent function of ViewContainerRef within your structural directives, follow the code snippet below:

@Directive({
  selector: "{Your-Selector}"
})
export class StructuralDirective implements OnInit {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private resolver: ComponentFactoryResolver
  ) {}

  @Input() {Your-Selector}: boolean;

  ngOnInit() {
    if (this.{Your-Selector}) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      let factory = this.resolver.resolveComponentFactory({Your component that holds default message});
      this.viewContainer.createComponent(factory);
    }
  }
}

Don't forget to include

{Your component that holds default message}
in your entry components.

You can check out a demo on CodeSandbox for reference.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

`The validation in Angular 12 is successful, yet the mat-input remains invalid.`

Code snippet of Component- ngOnInit(): void { this.form = this.fb.group({ currentPassword: ['', [Validators.required], [this.matchCurrentPassword]], newPassword: ['', [Validators.required, Validators.minL ...

Updating An Angular Application from version 11 to version 12 Challenge

Once I completed installing all the required dependencies as per: https://update.angular.io/ I executed the command 'ng serve' in the terminal and encountered the following errors: ./node_modules/leaflet/dist/images/marker-icon.png:1:0 - Error: ...

A guide to uploading multiple files in Angular 6 using the ADDMORE button

Greetings everyone! I'm currently facing a challenge with uploading multiple files in a single form which includes an array of objects with files. While handling a single file upload is straightforward, dealing with multiple files in an array poses a ...

Navigating the complexities of defining conditions in routes within Angular/ionic applications may seem daunting,

Utilizing the ionic 5 framework for building an application, I am looking to implement a condition in the route to redirect users if they are already signed in. Within the app-routing.module.ts file: const routes: Routes = [ { path: '&apo ...

How can one break down enum values in typescript?

I've defined an enum in TypeScript as shown below: export enum XMPPElementName { state = "state", presence = "presence", iq = "iq", unreadCount = "uc", otherUserUnreadCount = "ouc", sequenc ...

Having trouble with the npm install command in an Angular 7 project?

After downloading a project from git that is written in angular 7, running the npm install command shows an error. Here's the error message: npm ERR! code E404 npm ERR! 404 Not Found: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data ...

What are the recommended best practices for displaying loading indicators, alerts, and logs in Ionic2?

Seeking the most effective way to handle loadings, alerts, and console logs in Ionic2. Instead of duplicating the following code on every page, I want to be able to call it just once. Here is an example code snippet for showing loading: showLoading() ...

Does Angular2 restrict directives to just one root element?

Within Angular1, suppose I have a template for my-directive structured as follows: <li>First element</li> <li>Second element</li> <li>Third element</li> Now, if I wish to utilize this directive in the following manner: ...

The Angular Tooltip feature is unable to interpret the characters "' '" or "' '"

Let me explain the scenario: I am receiving a list of objects from my back-end service, which I then break apart using ngFor and display accordingly. Each item in the list has an associated toolTip that provides additional information. The info for each i ...

Modifying the Iterator Signature

My goal is to simplify handling two-dimensional arrays by creating a wrapper on the Array object. Although the code works, I encountered an issue with TypeScript complaining about the iterator signature not matching what Arrays should have. The desired fu ...

What are the appropriate scenarios to utilize the declare keyword in TypeScript?

What is the necessity of using declare in TypeScript for declaring variables and functions, and when is it not required? For instance, why use declare var foo: number; when let foo: number; seems to achieve the same result (declaring a variable named ...

Ways to resolve TypeScript type issues that are functioning correctly with one type but encountering errors when used with functions

When the route function encounters the middlewares parameter type, it always throws an error. However, no error occurs if the type is used directly, as seen in lines 72 and 75. Errors will occur on lines 107 and 98. abstract class BaseMiddleware< In ...

What is the process for sending values to a component?

I am working with a component called MyComponent: export class MyComponent { @Input() active:boolean; constructor() { console.log(this.active); } } In this component, I have declared an Input, and I pass it in as follows: <mycomp ...

Oops! A mistake was made by passing an incorrect argument to a color function. Make sure to provide a string representation of a color as the argument next time

Encountering an issue with a button react component utilizing the opacify function from the Polished Library The styling is done using styled-components along with a theme passed through ThemeProvider. Upon testing the code, an error is thrown. Also, the ...

Angular 4 in combination with ngx-datatable is showing a 404 error for the @swimlane/ngx-datatable package

Just starting out with Angular and I kicked things off by running this command: git clone https://github.com/angular/quickstart appName I've made the upgrade to Angular 4 and everything seems to be in order. Here's the output I got after running ...

Unable to retrieve information from Mat Select option

I'm encountering an issue with my code where I can see the options but cannot retrieve the value when selecting one. It just displays blank. The problem seems to be related to viewing only the status options. Does anyone have a solution to fix this? ...

Maximize the performance of displaying images

At the moment, I have a set of 6 graphics (0,1,2,3,4,5)... The arrangement of these graphics looks fantastic! However, I am facing an issue when a user only has 3 graphics, for example 0, 2, and 5. In this scenario, my graphics do not line up correctly. D ...

When using html2canvas in Angular, it is not possible to call an expression that does not have a call signature

I'm currently working on integrating the html2canvas library into an Angular 8 project. Despite trying to install the html2canvas types using npm install --save @types/html2canvas, I'm still facing issues with its functionality. Here's how ...

Setting up an OR guard in NestJS is a crucial step in managing

I need to secure a controller route using Guards, including IsAuthentifiedGuard, HasRoleGuard, and IsSafeGuard. I want the route to be accessible if at least one of these conditions is met: IsAuthentifiedGuard and HasRoleGuard pass IsSafeGuard passes For ...

Assign a class to the following element using an Angular 2 Directive

I have a dropdown menu and I want to incorporate an Angular2 directive to control the opening and closing of this dropdown. How can I apply the open class to the latest-notification div, knowing that my directive is applied to the button tag? Below is my ...