Guide on using a double tap to initiate an action on IONIC 4

Currently, I am exploring a tutorial that demonstrates how to implement a double tap feature in Ionic 4 to create an event.

If you're interested, you can check out the tutorial here.

Following the steps in the tutorial, I have installed Hammer JS and imported it into my main.ts file.

import 'hammerjs'

In addition, my app module setup looks like this,

import { AngularFireFunctionsModule, FunctionsRegionToken } from '@angular/fire/functions';
import { DoubleTapDirective } from './directives/double-tap.directive'

export class CustomHammerConfig extends HammerGestureConfig {
  overrides = {
    'press': {time: 500},  // default: 251 ms
    'pinch': {enable: false},
    'rotate': {enable: false},
  };
} 
@NgModule({
  declarations: [AppComponent, DoubleTapDirective],
  imports: [
    HttpModule,
    BrowserModule,
  providers: [
    Camera,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
 {provide: HAMMER_GESTURE_CONFIG, useClass: CustomHammerConfig},
 ],
  bootstrap: [AppComponent]
})

export class AppModule {}

One key element of the setup is the Double Tap Directive,

import { Directive, EventEmitter, HostListener, Output } from '@angular/core';

@Directive({
  selector: '[doubleTapable]'
})
export class DoubleTapDirective {

  @Output() doubleTap = new EventEmitter();
  @Output() tripleTap = new EventEmitter();

  constructor() {}

  @HostListener('tap',  ['$event'])
  onTap(e) {
    if (e.tapCount === 2) this.doubleTap.emit(e);
    if (e.tapCount === 3) this.tripleTap.emit(e);
  }
}

After implementing this setup in my app, I tried to enable a double tap feature where users can add posts to their favorites by double tapping on them in the feed. However, the current implementation is not working as expected. When double tapped, the app navigates to the post details page instead of triggering the doSomething() event.

Here's a snippet of the code from Tab4.html,

<div  (doubleTap)="doSomething()"  id ="post" *ngIf="posts" >
          <ion-card *ngFor ="let post of posts" [routerLink]="['/tabs/details-feed/', post.postID]">
          <div id ="profileImage" >
           <img id ="profileImageIn" [src]="post.profileImage">
          </div> 
          <div  id ="userName" ><h6>{{post.username}}</h6></div>
          <img [src]="post.image">
        </ion-card>
         </div>  

And the corresponding code from Tab4.ts,

import { ToastController } from '@ionic/angular';

 constructor(
    private aff: AngularFireFunctions,
    public toastController: ToastController
    ) {
  async  doSomething() {
      const toast = await this.toastController.create({
        message: 'Added to favorites.',
        duration: 2000
      });
      toast.present();
    }

I am seeking assistance in successfully implementing the double tap event. Any suggestions or insights would be greatly appreciated.

Answer №1

It appears that the problem lies in the configuration of the router on the element that is the child of your tappable. Take a look at the routerLink attribute below:

<ion-card *ngFor ="let post of posts" [routerLink]="['/tabs/details-feed/', post.postID]">

When a user interacts with your component, the sequence of mouse or touch events is crucial. The low-level events like touchstart, touchmove, and others will be triggered first, followed by more complex events like click:

  • touchstart
  • touchmove
  • touchend / touchcancel
  • mouseover
  • mousemove
  • mousedown
  • mouseup
  • click

It's important to note that "tap" events are not officially recognized by browsers, and are usually handled by libraries like hammer.js.

To work with tap/double tap events, consider removing the router link. This will allow the tap events to be properly detected by hammer.js before any router navigation.

You'll need to implement logic that waits for a double tap, and if the time between taps is too long, then trigger the router navigation to the detail page.

For a helpful example using hammer.js, check out this codepen: https://codepen.io/jtangelder/pen/pBuIw

I hope this explanation clarifies things for you.

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 ReplaySubject is receiving an updated response, however, the View is displaying the same information

Having an issue with the ReplaySubject in my code. It seems that after updating an Array, the new values are not reflecting on the UI. I can only see the old values unless I reload the page. I have tried using ngZone but it didn't help. The code is d ...

Accessing embedded component within an Angular template

I have a ng-template that I utilize to generate a modal with a form on top of one of my other components like this: <div> <h1>Main component content...</h1> <button (click)="modals.show(newthingmodal)">Create New T ...

Upgrading my loop React component from vanilla JavaScript to TypeScript for improved efficiency and functionality

After seeking assistance from Stack Overflow, I successfully created a loop in React using a functional component that works as intended. However, I am encountering errors while trying to refactor the loop to TypeScript. The code for my DetailedProduct c ...

Is it possible for RouteData in Angular 2 to transmit variables from a parent component to routed components?

How can I pass a variable from my AppComponent to CoursesComponent using RouteConfig? The "data" property in route config seems to only accept constant parameters and cannot recognize "this". Is there a workaround for this limitation? If not, what is the ...

When trying to install my npm package from the registry, I keep encountering an issue despite being able to install it locally

I recently released my Node.js/typescript package on the npm registry, but I'm encountering issues when trying to install it from there. Oddly enough, local installation works perfectly fine. Here's the output from the local installation: $ npm ...

Can you explain the significance of syntax in sample code (typescript, react)?

const sampleFunction: (inputString: string) => string = inputString => { return inputString.split(""); } I'm a bit confused about the code below and would appreciate some clarification. I understand that only "string" as a type is accepted, b ...

The incorrect child output is causing the observable to trigger erroneously, resulting in the observable receiving inaccurate

For quite some time now, I've been struggling to identify the issue in my code. The scenario is that I have a child component acting as a modal, which includes a search bar. When the user interacts with the search bar, it triggers an event to the pare ...

Exploring the options variables within CLI commander Js action

As a newcomer to developing CLI apps, I've chosen to work with ts-node and commander. However, I'm currently facing a challenge in understanding how to access the options that users pass into my command action. program .version(version) .nam ...

Customize React Hook Form version 7 by incorporating a unique input method for handling empty values

Introducing my custom Input component: export type InputProps = { error?: string } & InputHTMLAttributes<HTMLInputElement> export const Input: FunctionComponent<InputProps> = ({ error, ...props }) => ( <input {...props} /> ) ...

Utilizing a variable string name for a method in Typescript Vue

My objective is to trigger a different function based on the value of a variable. However, when working in VS Code, I receive an error message that states: 'method' implicitly has a type of 'any' because 'type1Func' and &apos ...

Issues with Vercel's JavaScript Environment Variables Accessibility

I am encountering an issue trying to access environment variables on Vercel using JavaScript (TypeScript). Despite setting them under /settings/environment-variables, I receive undefined when attempting to access them with process.env.TURSO_DATABASE_URL du ...

Is it possible to limit the items in a TypeScript array to only accept shared IDs with items in another array?

I'm creating an object called ColumnAndColumnSettings with an index signature. The goal is to limit the values of columnSettings so that they only allow objects with IDs that are found in columns. type Column = { colId: string, width?: number, s ...

Exploring the world of Typescript class decorators and accessing its content from within

Greetings, I am searching for a method to define a class in TypeScript and retrieve its value from within the parent. abstract class Base{ fetchCollectionName(): string{ // code here to return child class attribute value } } @Collectio ...

Creating fixtures with Playwright is a simple process that can greatly enhance

I have a requirement to set up fixtures where the first fixture is always available (acting as a base class) and the second fixture will vary in different test files (like a derived class). I've implemented the following code which seems to be working ...

Is it advisable to utilize Bootstrap for utility classes in conjunction with Angular Material for UI components?

Bootstrap provides a variety of useful helper utilities [such as padding and flex layout] that can be accessed by simply importing its CSS file [without the need for the js file, which contains all the components like calendars, etc]. Would it make sense ...

Angular 2 setting a class property to the output

There seems to be an issue with logging to the console in my getProfile() method. When I assign this.user to user, it does not return my json object as expected. If I write the following code: getProfile() { this.userService.getPortInfo() .th ...

Is there a specific Angular signature pad that is capable of saving signatures as images?

I'm looking to create a signature pad for saving user signatures on my enterprise website. Can anyone recommend the best package for this task? ...

Navigating with Angular 2 router while authenticating with AngularFire2

Currently, I am working on a route where I need to wait for the auth object from Firebase before proceeding. Below is the code snippet that I have implemented: Route { path: 'random', component: RandomComponent, resolve: { auth: AuthServi ...

Fixing the "tl-node is not recognized" error in VS Code and TypeScript

After installing VS Code, I am struggling to figure out how to compile TypeScript code in VSCODE. Some resources mention that VSCODE includes a "stable" version of TypeScript, while others suggest installing TypeScript separately. When I try to write the ...

experimenting with asynchronous promises in Jasmine to test Angular 2 services

Currently, I'm facing some challenges while testing my Angular 2 service. Even though my tests are passing, I keep encountering this error in the console: context.js:243 Unhandled Promise rejection: 'expect' was used when there was no c ...