Preventing Directive Angular 2 from Triggering Stop Button Click Event

I created my application using angular 2 and PrimeNG. I am trying to implement directives for checking user authority when a button is clicked. The issue I am facing is that even though there is no authority, the click event continues to be triggered. How can I halt the process if the checkAuth() function returns false?

This is a blockquote

@Directive({
    selector: '[checkAuthOnClick]'
})

export class CheckAuthorizationOnClickDirective {

    user: Observable<User>;
    @Input() allowedClaim: any;
    observer: MutationObserver;

    constructor(private element: ElementRef, private store: Store<fromRoot.State>) {
        this.element = element.nativeElement;
    }

    @Output()
    stop: EventEmitter<Event> = new EventEmitter;

    @HostListener('click', ['$event, $event.target'])
    onClick(event, targetElement) {  
        if (!this.checkAuth()) {
            event.stopPropagation();
            event.preventDefault();
            event.cancelBuble = true;
            event.stopImmediatePropagation();

            this.stop.emit(event);
        }
    }   

    private checkAuth(): boolean {
        this.user = this.store.select(fromRoot.currentUser);
        if (this.user != undefined && this.allowedClaim != undefined) {
            var hasClaim = false;
            var description;
            this.user.subscribe(x => {
                if (Array.isArray(this.allowedClaim)) { 
                    for (let i = 0; i < this.allowedClaim.length; i++) {
                        hasClaim = x.hasClaim(this.allowedClaim[i])
                        if (hasClaim)
                            break;
                    }

                    description = this.allowedClaim[0].Description;
                }
                else {
                    hasClaim = x.hasClaim(this.allowedClaim);
                    description = this.allowedClaim.Description;
                }
            });

            if (hasClaim == false) {
                var message = "You do not have permission for this action.";
                if (description != undefined) {
                    message = description + ' You do not have permission.'
                }

                this.store.dispatch(new ui.ToastMessagePushAction({ severity: 'warning', summary: message, detail: '' }));
            }
        }

        return hasClaim;
    }

}

Using this directive in HTML would look like this;

<button type="button" pButton icon="fa fa-file-code-o" (click)="createForm()" checkAuthOnClick [allowedClaim]="systemDefinedClaims?.CreateInvoiceDesign"></button>

Answer №1

When you bind an event using (click) and HostBinding, it means that you are binding two events independently to your target elements. These events will be triggered simultaneously and they do not affect each other. This implies that stopping one event will not stop the other.

In order to make sure that the click event (which is currently bound via (click)) is also triggered within your directive's click event bound by HostBinding, you need to manually call it.

// transfer click event into directive
@Input('clickEvent') clickEvent;


@HostListener('click', ['$event, $event.target'])
onClick(event, targetElement) {  
    if (!this.checkAuth()) {
        event.stopPropagation();
        event.preventDefault();
        event.cancelBubble = true;
        event.stopImmediatePropagation();

        this.stop.emit(event);
    } else {
        this.clickEvent();
    }
}    

Take a look at a demo example.

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

I'm trying to figure out how to incorporate types for utilizing Intl.ListFormat in node v12. Can

I am currently working with nodeJS version 12.10.0, which now includes support for Intl.ListFormat. I am also using Typescript version 3.6.3. However, when compiling my code with Typescript, I encounter the following error: Property 'ListFormat' ...

Using ng-template in child component from Parent Component in Angular

I am facing a situation where I have a BaseComponent and IncomingRequestsComponent that inherit from BaseComponent. To utilize templates in components that inherit from BaseComponent, I need to include them in the HTML of BaseComponent. export class BaseTi ...

Creating a composite object in Angular 2 reactive forms: a step-by-step guide

These are the two classes I have: export class Machine { name = ''; computer = new Computer() } export class Computer { os = ''; } Then in my component, using reactive forms, I have: ngOnInit() { this.form = this.fb ...

Identifying changes in a property's value binding within Angular 4

One way to detect changes in a property decorated with @Input is by implementing the OnChanges interface: export class EmployeeComponent implements OnChanges { @Input() message: string; startDate: Date; ngOnChanges(changes: SimpleChanges) { fo ...

Angular ListView and GridView is a powerful feature that allows developers to display

I am looking to create Listview and Gridview components using Angular with the following features: Paging Sorting Filtering Searching In addition, the Gridview should also have support for Nested Gridview. What are currently the most commonly us ...

The properties required for type 'never[]' are not present

The type 'never[]' does not have the necessary properties from type '{ login: string; id: number; node_id: string; avatar_url: string; url: string; }': login, id, node_id, avatar_url, url When working on a component that takes an ApiUr ...

What causes TypeScript generics to infer varying types when an array member is enveloped?

I'm having trouble finding an answer to this potentially duplicate question, so please redirect me if it has already been addressed. My experience with generics in TypeScript has shown me that the inferred types can vary based on whether a generic is ...

Using Javascript to parse SOAP responses

Currently, I am working on a Meteor application that requires data consumption from both REST and SOAP APIs. The SOAP service is accessed using the soap package, which functions properly. However, I am facing challenges with the format of the returned data ...

What is the best way to loop through a formarray and assign its values to a different array in TypeScript?

Within my form, I have a FormArray with a string parameter called "Foo". In an attempt to access it, I wrote: let formArray = this.form.get("Foo") as FormArray; let formArrayValues: {Foo: string}[]; //this data will be incorporated into the TypeScript mod ...

Utilizing the Solana Wallet Key for ArweaveJS Transaction Signing

Is there a method to import a Solana wallet keypair into the JWKInterface according to the node_modules/arweave/node/lib/wallet.d.ts, and then generate an Arweave transaction using await arweave.createTransaction({ data }, jwk);? Metaplex utilizes an API ...

Is it possible for dynamically created injectors in Angular2 (created through Injector.create(...)) to be destructed at any point

Looking for insights on the lifecycle of injectors created using the Injector.create method I experimented with creating a component using ViewContainerRef.createComponent(...) and supplying dynamically generated dependencies through a custom injector pas ...

Encountering difficulty executing the angular-cli command to generate a production build

My Angular app runs smoothly in the development environment when I build it using the command npm run build. However, I encountered an error when trying to build it with the production tag: C:/Users/1234/app/src/$$_gendir/app/app.component.ngfactory.ts ...

The issue arises where Google Maps Platform rejects your request due to an invalid request with an unexpected parameter "amp%3Bkey"

Dealing with angular error Your request has been rejected by Google Maps Platform. It was flagged as invalid due to an unexpected parameter 'amp%3Bkey'. Here's the error displayed in the console: GET https://www.google.com/maps/embe ...

remove unnecessary parameters from a JavaScript object using curly braces

My query pertains to an object response below result.joblist = { "collection_job_status_list": [ { "application_context": { "application_id": "a4", "context_id": "c4" }, "creation_time": "15699018476102", "pro ...

Displaying data from an Angular subscription in a user interface form

I am attempting to transfer these item details to a form, but I keep encountering undefined values for this.itemDetails.item1Qty, etc. My goal is to display them in the Form UI. this.wareHouseGroup = this.formBuilder.group({ id: this.formBuilder.contr ...

Vue JS TypeScript component is unable to locate injected instance properties

Currently, I'm utilizing typescript alongside vue in my project. Within the app structure, there exists a service that acts as a global entity for all sub-components. I stumbled upon this native solution provided by Vue JS, which facilitates injecti ...

Angular and Webpack combined to output the build project to the specified output path

In the process of integrating my Angular client-side application with a server-side written in Spring, I am seeking a way to build the UI project and store it in the /target directory within the backend portion for easy installation using Maven. My uncer ...

How can `${}` be utilized within Angular applications?

Within TypeScript component files in Angular projects, I often come across this particular syntax enclosed in backticks: <div ${selector} [inDemo]="false" [config]="demoConfig">Demo Content</div> I'm curious about the purpose of the ${} ...

Is there a user-friendly interface in Typescript for basic dictionaries?

I'm not inquiring about the implementation of a dictionary in Typescript; rather, I'm curious: "Does Typescript provide predefined interfaces for common dictionary scenarios?" For instance: In my project, I require a dictionary with elements of ...

Utilizing Bootstrap-Table with Ionic Angular for dynamic table functionality

I am looking to incorporate Bootstrap Table into my Ionic project. It seems like a user-friendly and highly responsive option for Hybrid Web Apps. Additionally, I am in the process of transitioning my Angular project to Ionic, which already utilizes Bootst ...