0

I have Timer function, that does countdown. I move it from js to ts code

Here is code of function (TS)

  export module Timer {
   export function startTimer(duration, display){
    let session_timer;
    Date.now = Date.now || (() => +new Date);
    const start = Date.now();
    let diff = 0;
    let minutes:any = 0;
    let seconds:any = 0;
    const timer = function() {
        diff = duration - (((Date.now() - start) / 1000) | 0);
        minutes = (diff / 60) | 0;
        seconds = (diff % 60) | 0;
        if (minutes < 0) { minutes = "0"; }
        if (seconds < 0) { seconds = "0"; }
        minutes = minutes < 10 ? `0${minutes}` : minutes;
        seconds = seconds < 10 ? `0${seconds}` : seconds;
        display.html(`${minutes}:${seconds}`);
        if (diff <= 0) {
          $(this).changePage('#session_timer');
          return clearInterval(session_timer);
        }
      };

      timer();
      return session_timer = setInterval(timer, 1000);
   };

}


export default Timer;

I importing it to index.ts, webpack component like this

import Timer from "./scripts/timer";

export default Timer;

And than call in step2.js pack

Like this

 import Timer from "../components/timer";

$(document).ready(() => {
  Timer.startTimer();
});

But when I try to run project I have this error

TypeError: Cannot read property 'html' of undefined

JS Code is was this

 window.startTimer = function(duration, display) {
    let session_timer;
    Date.now = Date.now || (() => +new Date);
    const start = Date.now();
    let diff = 0;
    let minutes = 0;
    let seconds = 0;

    const timer = function() {
      diff = duration - (((Date.now() - start) / 1000) | 0);
      minutes = (diff / 60) | 0;
      seconds = (diff % 60) | 0;
      if (minutes < 0) { minutes = "0"; }
      if (seconds < 0) { seconds = "0"; }
      minutes = minutes < 10 ? `0${minutes}` : minutes;
      seconds = seconds < 10 ? `0${seconds}` : seconds;
      display.html(`${minutes}:${seconds}`);
      if (diff <= 0) {
        $(this).changePage('#session_timer');
        return clearInterval(session_timer);
      }
    };

    timer();
    return session_timer = setInterval(timer, 1000);
  };

How I can fix it? In JS all working great

15
  • You are using a display variable. Where is it defined? Apparently is not, and hence the error. Commented Apr 17, 2018 at 10:36
  • It's in parameters. I updated post @OscarPaz Commented Apr 17, 2018 at 10:39
  • Well, apparently, if is undefined. Check it with console.log(display) just before calling display.html Commented Apr 17, 2018 at 10:40
  • What type does the Typescript compiler understand display to be? You might have to explicitly annotate it: display: JQuery. Commented Apr 17, 2018 at 10:42
  • Yes, it's undefined @OscarPaz Commented Apr 17, 2018 at 10:44

2 Answers 2

2

display is undefined because you're not defining it...

You need to call your function thus:

import Timer from "../components/timer";


let display = ;//whatever this is supposed to be?
//e.g. let display = $('.myClass'); 
//to pass in a html element of myClass.

$(document).ready(() => {
  Timer.startTimer(100, display);
});

I'm presuming this is supposed to be a jQuery HTML element and that is why your calling display.html(...)

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

2 Comments

And also because the OP stated in a comment that the call looks like this: startTimer(#{@search.session_timer}, $('#time_left'))
Yup, thank's for help.I will post full answer, that describes solving of my problem
0

So here is answer for my question

Since data was getting at past from View like this:

startTimer(#{@search.session_timer}, $('#time_left'))

I need function to get data from back end (from View is not working anymore).

So I make on back end variable gon.timer

So calling of my function in pack need to be like this

$(document).ready(() => {
  Timer.startTimer(gon.timer);
});

After this I need to call createTimer from startTimer like this

 import Helpers from "../../global/helpers";
import TimerFunctions from "./timer_functions";
declare let gon: any;
export module Timer {
   export function startTimer (duration){
    let display: JQuery;
    display= $('#time_left');
    TimerFunctions.createTimer(duration,display,(() =>
    $.fancybox.open($('.session_timeout'), {
      afterClose() {
        return Helpers.navigate(gon.links.like_url);
      }
    })
    ))
   }
};

export default Timer;

And finally createTimer function in another file

    export namespace TimerFunctions {
  let session_timer;
  export function createTimer(duration, display, func) {
    Date.now = Date.now || (() => +new Date());
    const start = Date.now();
    let diff = 0;
    let minutes = 0;
    let seconds = 0;

    const timer = function() {
      diff = duration - (((Date.now() - start) / 1000) | 0);
      let minutes: any = (diff / 60) | 0;
      let seconds: any = (diff % 60) | 0;
      if (minutes < 0) {
        minutes = "0";
      }
      if (seconds < 0) {
        seconds = "0";
      }
      minutes = minutes < 10 ? `0${minutes}` : minutes;
      seconds = seconds < 10 ? `0${seconds}` : seconds;
      display.html(`${minutes}:${seconds}`);
      if (diff <= 0) {
        clearInterval(session_timer);
        return func();
      }
    };
    timer();
    return (session_timer = setInterval(timer, 1000));
  }
};

export default TimerFunctions;

Now all working perfectly.

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.