64

I am attempting to use some code I found on https://github.com/bevacqua/dragula/issues/289#issuecomment-277143172 to my Ionic project.

When I run the code I get an error Cannot find namespace 'NodeJS' and the error refers to touchTimeout: NodeJS.Timer;

How can I adapt the code below to make the NodeJS.Timer line work?

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

@Directive({ selector: '[delayDragLift]' })
export class DelayDragLiftDirective {

    dragDelay: number = 200; // milliseconds
    draggable: boolean = false;
    touchTimeout: NodeJS.Timer;

    @HostListener('touchmove', ['$event'])
    // @HostListener('mousemove', ['$event'])
    onMove(e: Event) {
        if (!this.draggable) {
            e.stopPropagation();
            clearTimeout(this.touchTimeout);
        }
    }

    @HostListener('touchstart', ['$event'])
    // @HostListener('mousedown', ['$event'])
    onDown(e: Event) {
        this.touchTimeout = setTimeout(() => {
            this.draggable = true;
        }, this.dragDelay);
    }

    @HostListener('touchend', ['$event'])
    // @HostListener('mouseup', ['$event'])
    onUp(e: Event) {
        clearTimeout(this.touchTimeout);
        this.draggable = false;
    }

    constructor(private el: ElementRef) {
    }
}
1

4 Answers 4

111

Open src/tsconfig.app.json*.

Add "node" to the "types" array.

Example:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "es2015",
    "types": [
      "node"
    ]
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

*if this file does not exist add the specified part to tsconfig.json in root folder.

Sign up to request clarification or add additional context in comments.

Comments

35

A quick way to solve this problem is here.

Basically change setTimeout and clearInterval to window.setTimeout and window.clearInterval, respectively. For example, your onDown becomes:

onDown(e: Event) {
    this.touchTimeout = window.setTimeout(() => {
        this.draggable = true;
    }, this.dragDelay);
}

Then, your declaration becomes:

this.touchTimeout: number | undefined;

9 Comments

This should be accepted, since you shouldn't include node types into an Angular project which is targeting browsers.
Return type of setTimeout is not a number, it's of type NodeJS.Timeout
@AnandRaja You have violated the edit rules "When should I edit posts?" point 2: "To clarify the meaning of the post (without changing that meaning)". The author of this post points out that when setTimeout is called in a client-side application or website, it always calls window.setTimeout, which in fact returns a number, not a NodeJS.Timeout. Your edit should have been either a comment or a separate answer, both of which you actually did. :|
Hello @MartinSchneider, I have not violated the rule. You answer is wrong, that's why I had to edit it. The retun type is NodeJS.Timer. Could you please check your editor with this line private touchTimeout?: ReturnType<typeof setTimeout>;. This line will make you understand. Attachments are not allowed, otherwise, I could have added the one for your reference.
@AnandRaja In some editors the return type might be NodeJS.Timeout as they target the NodeJS runtime by default. But browsers (where an Ionic app is most probably run) do not share the same APIs with NodeJS. That's why this question here exists. Please open the console in your browser and run: let foo = setTimeout(() => console.log('hey'), 1000); typeof(foo). And even if I'm wrong, either way you changed the meaning of the original answer :P
|
1

if NodeJS.Timeout throws error, you can modify your variable declaration as below:

private touchTimeout?: ReturnType<typeof setTimeout>;

This special ReturnType provision will give you the type as NodeJS.Timeout.

FYI,

enter image description here

Comments

-3

To me, solve include the typeRoots member in compilerOptions from tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "es2015",
    "typeRoots": [
         "node_modules/@types"
     ]
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.