What is the best way to create a routerlink that is both single-clickable and double-clickable within an

There have been numerous instances where a similar question has been raised, but I am unable to make this work. Despite looking at various answers such as this one on Stack Overflow that don't seem to work for most users. While this may not be specifically an Angular issue, I am attempting to resolve it within my ng app.

I want the link to function normally when clicked. Moreover, I also want the item containing the link to be double-clickable to open the link in a split area beside the router-outlet. Therefore, in my navigation menu, I have:

<li *ngIf="propertiesTabVisible"  class="nav-item tab-nav-item"
      [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }' 
      (dblclick)="toggleTab('/properties/' + sessionId)">
      <a class="nav-link" [routerLink]='["/properties", sessionId]'
       [class.disabled]="(propertiesLinkDisabled | async)"
       (click)="navigateWithDelay('/properties/' +sessionId)">
        <mat-icon class="tab-nav-item-icon">assignment</mat-icon>
      </a>
    </li>

And in the component.ts file:

  private block = true;
  private isCancelled = false;

  private delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  private async sleepExample(url: string) {
    await this.delay(200);
    if (!this.block) {
      this.router.navigate([url]);
    }
  }

  navigateWithDelay(url: string) :boolean {
    this.block = true;
    this.isCancelled = false;
    this.sleepExample(url).then(() => {
      if (!this.isCancelled) {
        this.block = false;
      }
    });
    return false;
  }

  toggleTab(url: string) {
    this.isCancelled = true;
    toggleTabVisibility(url);
  }

However, despite both handlers being called and functioning as expected, the link propagation still occurs upon clicking. How can I prevent this propagation in the click handler?

Answer №1

Learn more about why $event.stopPropagation() and $event.preventDefault() do not work in routerLink by visiting this link.

Below is a functional example where the click event is transferred to a mat-icon within an anchor tag, and the handler successfully executes both functions:


    $event.stopPropagation();
    $event.preventDefault();

.html:

<li *ngIf="propertiesTabVisible"  class="nav-item tab-nav-item" [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }'
(dblclick)="toggleTab('/properties/' +sessionId)">
  <a class="nav-link" [routerLink]='["/properties", sessionId]' [class.disabled]="(propertiesLinkDisabled | async)">
    <mat-icon class="tab-nav-item-icon" (click)="navigateWithDelay($event, '/properties/' +sessionId)">assignment</mat-icon>
  </a>
</li>

.ts:

  
  toggleTab(url: string) {
    this.isCancelled = true;
    this.ngRedux.dispatch(this.actions.toggleWindowUrl({
      windowId: this.tabService.windowId,
      url: url,
      isSplit: true
    }));
  }

  private isCancelled = false;

  private delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  private async waitForDoubleClick() {
    await this.delay(200);
  }

  navigateWithDelay($event: any, url: string) {
    this.isCancelled = false;
    $event.stopPropagation();
    $event.preventDefault();
    this.waitForDoubleClick().then(() => {
      if (!this.isCancelled) {
        this.router.navigate([url]);
      }
    });
  }

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

What is the best way to ensure that Interface (or type) Properties always begin with a particular character?

I attempted to tackle this assignment using template literals, but unfortunately, I wasn't successful. Here is the interface that I am working with: interface SomeInterface { '@prop1': string; '@prop2': string; '@ ...

Determine the data type based on the object property

Can a versatile function be created to automatically determine the type based on an "external" object property? Consider the following scenario: const resolversMap: { overallRankingPlacement: (issuer: number, args: Record<string, any>, context: Re ...

When utilizing TypeScript, is it possible to indicate a different type for a null argument when calling a function?

I was intrigued by the behavior in TypeScript where line A compiles successfully while line B does not. function someFunction<T>(arg: T): void { console.log(arg) } someFunction<string>('some string') // this works fine someFunction ...

Using TypeScript to handle text resolution through the command line interface

Currently, I am developing a CLI application using TypeScript and employing enquirer for the purpose. More information about enquirer can be found here. In my project, I have a JSON object defined as follows: const person = { name: 'Mohan', ...

Enhancing the theme using material-ui@next and typescript

While developing my theme using material-ui, I decided to introduce two new palette options that would offer a wider range of light and dark shades. To achieve this, I extended the Theme type with the necessary modifications: import {Theme} from "material ...

What is the best way to determine the type of `rootReducer`?

My project is set up with a combination of React, Redux, Immutable.js, and TypeScript. As I worked on implementing it, I made an effort to declare types wherever possible which led me to discover an interesting issue. A code example illustrating the proble ...

Testing Angular Library Before Release

My Angular library consists of modules, each containing services. I am looking for a way to easily test my library when I make changes to one of the services. Is there a simple solution that doesn't involve publishing and installing it in the main pr ...

The ngOnChange() function in Angular 2 is not behaving as expected when called for the

I am currently working in Angular2 and facing an issue with passing data from one parent component to a child component. <app-datatable-repr [myFilterData]="filterData"></app-datatable-repr> The data being passed is stored in an object called ...

Exploring the Differences between Angular's Http Module and the Fetch API

While I grasp the process Angular uses for HTTP requests, I find myself leaning towards utilizing the Fetch API instead. It eliminates the need to subscribe and unsubscribe just for a single request, making it more straightforward. When I integrated it int ...

Is it possible to export an imported merged namespace in Typescript?

Within my library, I have a collection of merged declarations setup like this: export class Foo {...} export namespace Foo { export class Bar {...} ... } export default Foo These merged declarations often contain inner classes and specific errors r ...

Installation of Angular-cli was unsuccessful

Can you assist me with a query? I attempted to install the angular-cli using the npm command npm install -g angular-cli, but I encountered numerous error messages and the 'ng' command isn't working. Some of the errors I received include: ...

How come JSON.parse is altering the data within nested arrays?

In my journey to master Angular 2, I decided to challenge myself by creating a Connect Four game using Angular CLI back when it was still utilizing SystemJS. Now, with the switch to the new Webpack-based CLI, I am encountering a peculiar issue... The fun ...

retrieve asynchronous data from the server using ngrx

How can I retrieve asynchronous data from the server? I am looking to save this data in a global store for future updates. I'm having trouble grasping the concept of asynchronous calls, such as in Redux. While I was able to understand it with simpl ...

Issue with Angular detection on the webpage: Protractor and headless chrome unable to locate Angular

Running end-to-end tests on my Angular2 app using Chrome works perfectly fine. However, when attempting to use headless Chrome with additional chromeOptions, it fails to locate the Angular app. I have tried setting directConnect to true and starting the se ...

Solving the 'ExpressionChangedAfterItHasBeenCheckedError' in Angular 8

In my current project, I have developed a component that is responsible for uploading files to a database. As part of the user interface, I added an overlay that displays information about the number of files selected and the number of files successfully u ...

Encountering Error 203 while trying to establish a connection between Angular and Django Rest Api

I'm currently working on a project that involves creating a contacts system, but I've been encountering errors when trying to list them. Interestingly, I can successfully perform CRUD operations using Postman with the API. One of the messages I ...

The Vue CLI project, using Typescript, is facing challenges with building and running Mocha tests

My Vue 2 project, created using Vue CLi, is encountering numerous errors. While it compiles fine for development purposes, running unit tests or building for production results in a cascade of issues. Displayed below are some sample errors, along with sni ...

Make sure PTable maintains a horizontal layout on any device with PrimeNG

When I view my Ptable on desktop or iPad, it looks like this: https://i.stack.imgur.com/ONqZV.png However, when I switch to a device like an iPhone X, it changes to this layout: https://i.stack.imgur.com/H2q7j.png I want the horizontal layout to displa ...

Incorporating DefinitelyTyped files into an Angular 2 project: A step-by-step guide

I am currently developing an application using angular 2 and node.js. My current task involves installing typings for the project. In the past, when starting the server and activating the TypeScript compiler, I would encounter a log with various errors rel ...

Unlock the Power of RxJS Observables in Angular

Issue: My goal is to navigate to the login page if firebase-auth does not have a user logged in, and to an alternate page if a user is already logged in. To achieve this, I plan to call a function within a constructor service. private checkLoginStatus() ...