How to conditionally apply a directive to the same tag in Angular 4

I am implementing angular 4 and have a directive in my template for validation purposes. However, I would like to first check if a specific condition is true before applying the directive. Currently, my code looks like this:

<div *ngIf="groupCheck; else NoDirective" #Directive>
 <li [directive]="controlGroup"><a [routerLink]="['/account/search/', '']"
                    routerLinkActive="active">Accounts</a></li>
 <li [directive]="controlGroup"><a [routerLink]="['/orders', '']"
                    routerLinkActive="active">Orders</a></li>
 <li [directive]="DIFFERENT_GROUP"><a [routerLink]="['/report']" routerLinkActive="active">Reports</a>
                </li>
 <li [directive]="controlGroup"><a [routerLink]="['/anotherStuff']" routerLinkActive="active">Another Stuff</a></li>
</div>
<div *ngIf="!groupCheck; else Directive" #NoDirective>
 <li><a [routerLink]="['/account/search/', '']" routerLinkActive="active">Accounts</a></li>
 <li><a [routerLink]="['/orders', '']" routerLinkActive="active">Orders</a></li>
 <li><a [routerLink]="['/report']" routerLinkActive="active">Reports</a></li>
 <li><a [routerLink]="['/anotherStuff']" routerLinkActive="active">Another Stuff</a></li>
</div>

I am looking for a way to achieve something like this:

<li *NgIf="condition true add [directive]=controlGroup; else Don't add directive to this line/tag/element"><a [routerLink]="['/account/search/', '']"
                    routerLinkActive="active">Accounts</a></li>
 <li *NgIf="condition true add [directive]=controlGroup; else Don't add directive to this line/tag/element"><a [routerLink]="['/orders', '']"
                    routerLinkActive="active">Orders</a></li>
 <li *NgIf="condition true add [directive]=DIFFERENTGROUP; else Don't add directive to this line/tag/element"><a [routerLink]="['/report']" routerLinkActive="active">Reports</a>
                </li>
 <li *NgIf="condition true add [directive]=controlGroup; else Don't add directive to this line/tag/element"><a [routerLink]="['/anotherStuff']" routerLinkActive="active">Another Stuff</a></li>

This way, I can avoid rewriting the entire code for just one condition and eliminate the need for conditional div. Is there a way to accomplish this?

-----******UPDATE******----- @Allabakash provided me with a potential solution:

<button [attr.md-raised-button]="condition ? '' : null"></button>

My challenge now is that my directive (which I cannot access) removes the entire element if it receives null or a name not present in the method. Here's how it functions:

set checkGroup(hasGroups: string) {
    if (hasGroups) {
        this.AuthService.hasOtherGroups(hasGroups, false).subscribe(res => {
            if (!res) {
                this.el.nativeElement.parentNode.removeChild(this.el.nativeElement);
            } else {
                this.el.nativeElement.style.display = '';
            }
        });
    } else {
        this.el.nativeElement.parentNode.removeChild(this.el.nativeElement);
    }
}

So, my main question is: Is there a way to use this directive with a condition inside the <li> tag that allows me to apply the directive on the element, and if the result is null, prevent the directive from being applied, thus avoiding repeating the entire menu?

Thank you for your assistance :).

Answer №1

Consider these two options:

  • Include your condition within your directive to transmit data to it
  • You can also achieve the desired outcome by using ngIf on multiple elements:

    <div *ngIf="false"></div>
     <div *ngIf="true" myDirective></div>

Answer №2

Learn how to create a custom structural directive, pass in parameters, and execute custom logic within it... For example:

@Directive({ selector: '[myDirective]' })
export class MyDirective implements OnInit {
    private _config;

    @Input()
    set myDirective(config) {
        this._config = config
    }

    constructor(
        private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef
    ) {}

    ngOnInit() {
        if (this._config) {
            this.viewContainer.clear()
        } else {
            this.viewContainer.createEmbeddedView(this.templateRef);
        }
    }
}

This is just a sample, but you have the freedom to trigger any actions based on various events such as changes in Input, emission of observables, and more...

Implement the structural directive similar to how you would use ngIf...

<ng-container *myDirective="config"></ng-container>

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

"Encountering issues when trying to retrieve a global variable in TypeScript

Currently facing an issue with my code. I declared the markers variable inside a class to make it global and accessible throughout the class. However, I am able to access markers inside initMap but encountering difficulties accessing it within the function ...

Access denied: Unable to rename directory '/usr/local/lib/node_modules/expo-cli' due to permission restrictions

After encountering an error that appeared to be related to permissions, I spent some time troubleshooting and finally found a solution. I wanted to share it here in case it can help others facing the same issue. If anyone has alternative solutions, please ...

Move forward state using navigateByUrl in Angular

I am looking to send data when changing the view using navigateByUrl like this: this.router.navigateByUrl(url, {state: {hello: "world"}}); Once in the next view, my goal is to simply log the hello attribute like so: constructor(public router: Router) { ...

Using Angular 4 to delete selected rows based on user input in typescript

I am facing a challenge with a table that contains rows and checkboxes. There is one main checkbox in the header along with multiple checkboxes for each row. I am now searching for a function that can delete rows from the table when a delete button is clic ...

How can I encode and decode a base64 string using AngularJS1 and TypeScript?

I am currently working with Angular1 using TypeScript and I have a question that needs some clarification. Within the environment that I am operating in, is there a method available to encode and decode a string in base64? Despite conducting extensive re ...

Generate a <mat-error> element dynamically and ensure it is correctly projected into the parent <mat-form-field> component

Creating a component dynamically using the ComponentFactoryResolver is relatively simple, but I have encountered an issue when attempting to project the created component into its parent when working with the Angular Material <mat-error> component in ...

Visual Studio is refusing to highlight my code properly, intellisense is failing to provide suggestions, and essential functions like go to definition are not functioning as expected

Due to a non-disclosure agreement, I am unable to share any code. However, I am experiencing an issue with Visual Studio not highlighting my code or allowing me to utilize its built-in tools. While I can rebuild the project, I cannot edit or access any fil ...

Is there a way to determine the port being used by the http-server?

After using the command prompt to install the HTTP server with npm install http-server -g, I received a relevant path but no port number. How can I determine what the port number is? http://localhost:8080/index.html I encountered an error on IIS 8.5. ...

The functionality to verify the presence of a child element is not functioning correctly when using

Trying to determine the existence of a child, I have created a new Firebase list observable and also attempted with an object observable. Upon creating the observable, I verify if it exists or not; however, it always returns false. Database Structure: {R ...

Asynchronous data binding in Angular 2

I'm trying to pass a value from my ImageDetail component to the ImageComment component as follows: ImageDetailHtml: <image-comment [photo]="photo"></image-comment> ImageCommentComponent: export class ImageCommentComponent { @Input(&a ...

Having trouble with running the command ng update -g @angular/cli, receiving an error message

When running the command ng update -g @angular/cli I encountered the following issue: Unexpectedly, an error occurred stating package amcharts3-angular2 has no version null while trying to execute the ng update -g @angular/cli command. ...

What strategies can I implement to streamline the use of these functions instead of creating a separate one for each textfield

Currently, I am learning how to use spfx with SPO (SharePoint Online). In my form, there are multiple text fields that need to be handled. I have two class components named A and B. Whenever a textfield in component B is typed into, a function sends the in ...

Angular component injected with stub service is returning incorrect value

While attempting to write tests for my Angular component that utilizes a service, I encountered an issue. Despite initializing my userServiceStub property isLoggedIn with true, the UserService property appears false when running the tests. I experimented ...

Testing a React component that utilizes RouteComponentPropsTesting a React component with RouteComponentProps

One of my components has props that extend RouteComponentProps defined as follows: export interface RouteComponentProps<P> { match: match<P>; location: H.Location; history: H.History; staticContext?: any; } When I use this component i ...

Tips on optimizing data processing for quicker display with ngFor

I am currently facing an issue with loading a JSON file containing 3500 data. The data appears very slowly on the view, causing the application to work sluggishly. Below is a snippet of the JSON: export class Service { private items = new Arr ...

Can I format fixed text alongside a label in an angular material form to match the styling of an input, ensuring they have consistent typography?

I am currently creating a form using Angular material. I want to add static text and a styled label that mimics a form input without interactivity or underlining. By using a custom class, I managed to achieve this effect: <mat-form-field floatLa ...

Exploring objects nested within other types in Typescript is a powerful tool for

My journey with TypeScript is still in its early stages, and I find myself grappling with a specific challenge. The structure I am working with is as follows: I have a function that populates data for a timeline component. The data passed to this function ...

Guide to retrieving an array of arrays in Angular 2

How do I retrieve an array of array data in Angular 2? The JSON data I have is as shown below, [[{ "pk_emp_id":5, "tenant_id":"Zone1", "location_id":1, "emp_number":"sk44", "prefix":"", "first_name":"qqqqq", "middle_name":"www", "last_nam ...

Switching Angular fxLayout from row to column based on a conditional statementHere is an explanation of how to

Visit this link for more information Is there a way to set direction based on a specific value? <div if(value) fxLayout='row' else fxLayout='column'> ...

The argument passed to the AsyncPipe is not valid: '[object Object]'

Provided as shown below: public currentDBUserBS$: any; constructor(private afDb: AngularFireDatabase){} fetchUser(uid){ this.afDb.object(`users/${uid}`).valueChanges().subscribe((dUser) => { if (dUser) { this.currentDBUserBS$ = dUser; ...