Stuck implementing a Promise as part of a Construct – Need Help

Stuck implementing a Promise as part of a Construct – Need Help
0

#1

Hi everyone,

I am working on my Pomodoro timer and I’m finding myself chasing my own tail and need some help.

But first some background: I’ve setup a function which returns a setInterval based Promise that updates and checks the screen every second producing a countdown. Once the first timer (work timer) reaches zero, I call the function again using ‘then’ for the rest period. This in its rudimentary way works fairly okay.

I now want to give my construct some properties as getters and setters so i can control the state of the timer such as pause, start, stop, reset, stuff like that. This is where I start getting errors I don’t know how to overcome.

Here is the relevant part of the code I am having issues with.

This works:

//setup construct
    var Timer = function () {
        var duration = 0;
        this.setDuration = (num) => duration = num;
        this.getDuration = () => duration;
    }
//use my construct
    var myTimer = new Timer();
    myTimer.setDuration(9);
    console.log(myTimer.getDuration());

when I run the code, I get 9. Perfect :slight_smile:

This does not work:

//setup construct
    var Timer = function () {
        var duration = 0;
        this.setDuration = (num) => duration = num;
        this.getDuration = () => duration;
        return new Promise(resolve => {
            //do timer and screen update stuff here
                    resolve();
        });
    }
//use construct
    var myTimer = new Timer();
    myTimer.setDuration(9);
    console.log(myTimer.getDuration());

when I run this code I get
TypeError: myTimer.setDuration is not a function
:frowning:

I know the issue is to do with how I am implementing or calling the lexical This. And I have a feeling it can be fixed with a bind, call, apply, or something of that sort. The thing is, I’ve been at this for three days and after reading a handful of tutorials, and YouTube videos I am not making any progress. I think I understand the basic concept but I don’t know how to apply it here.

Any help would be much appreciated

RockLobster7

PS. for the record; i know i can and have gotten the timer functionality working using global variables, but due to my compulsive pig-headedness, i really want to get this working as a construct / class.


#2

I think the reason why you get that error is that the object in myTimer is the returned Promise. When you remove the return new Promise, the new Timer() call would then return an object with setDuration and getDuration properties.


#3

I am not sure what you are trying to accomplish here but this is what I have done that fixes your code:

var Timer = function () {
  var duration = 0;
  this.setDuration = (num) => duration = num;
  this.getDuration = () => duration;
  return new Promise(resolve => {
    resolve(this);
  });
}
    
var myTimer = new Timer();

myTimer.then((timer) => {
  timer.setDuration(10);
  console.log(timer.getDuration())
})


#4

Hi @kevcomedia ,

thanks for replying. Yes removing the return promise does fix the issue of not being able to call upon the getters and setters. Thing ist i need the promise to chain my timers. So i cant do without it.

I guess returning a promise returns an object from within the Timer object itself which is stopping me from accessing my get and set objects.

Am i going about this the wrong way?

RockLobster7


#5

hi @michal9909,

thank-you for taking a look. I ran your code and it does stop the errors. Only problem is that ‘resolve(this)’ waits for the promise to finish before i can access the getters and setters which is not what i am trying to accomplish.

I’d like to create a ‘Timer’ object which i can have methods to start, stop,and pause it with calls like Timer.Start() Timer.Stop() Timer.Pause().

i would also like to query this object for its status, e.g. Timer.isPaused() and having it return a True or False.

and set properties like Timer.setDuration(25), then start the timer with a Timer.Start().

I may be going about this all back to front, so any help would be beneficial. Only stipulation is that i’d like to stick to the Promise pattern, rather than callbacks to chain timers.

Thanks
RockLobster7


#6

You are using the promise in a bad way i think…
Look at these Promise Examples

And i don’t know what are you exactly doing… Your promise would return what? A promise? remember that promise is an object…
And, just as a good practice, be sure you always include the reject argument.


#7

Yeah, it’s a bad example of using a promise. I quickly came up with an example of how Promise could be used to fix RockLobster7’s error.

Your promise would return what? A promise?

I believe that promise would return an instance of the Timer.

And, just as a good practice, be sure you always include the reject argument.

I do agree with that.


#8

I tend to agree that this is not a good usage of promises. As far as I understand, the purpose of a promise is to facilitate asynchronous requests that have not been fulfilled yet, however setTimeout / setInterval already come equipped with callback functions that are invoked at the end of a specified cycle, in a sense, the invocation of these functions are the fulfillment of a promise, so creating a new separate promise in this case would be redundant


#9

hi @Dereje1,

you’re correct in your statement in that “the purpose of a promise is to facilitate asynchronous requests that have not been fulfilled yet”.
The reason i have configured the promise is to configure an asynchronous timer to keep a countdown whilst updating the screen. The purpose for the object is to get a status on the asynchronous task so i can query if its running so i can pause it and reset it.

Admittedly i could’ve explain what i was trying to do a little clearer. Anyway, i take your comments onboard. There may be a better way to do this, but i figured this Pomodoro timer was a good and simple opportunity to learn promises. that’s why i am persisting with it :slight_smile:

Cheers
RockLobster7


#10

Hi everyone,
thanks for taking the time to reply to my post. All your comments had me rethinking my approach and i’ve worked out that this is what my object should look like:

//setup construct
var Timer = function () {
    var duration = 0;
    this.setDuration = (num) => duration = num;
    this.getDuration = () => duration;
    this.start = () => {
        return new Promise(resolve => {
                //do timer and screen update stuff here
                resolve();
            }
        });
}
//use construct
var myTimer = new Timer();
myTimer.setDuration(9);
myTimer.start();

This works, all i had to do was assign the promise to a method called ‘start’. This gives me an object i can set and manipulate the asynchronous timers with a tidy API. Or at least that’s the idea. I am still playing around with structure but i am over this hurdle.

Thanks :slight_smile:
RockLobster7


#11

This code runs properly? I was looking at it to check out what you did here and it seems like there are some brackets out of order here or am I crazy? I’ll admit I could very well be crazy. @RockLobster7


#12

HI @iamknox, sorry for the late reply (xmas activities and all that). I haven’t logged on in a while. Yes the code runs properly. I just finished implementing it into my Pomodoro Clock, you can see the pen working here https://codepen.io/RockLobster7/full/WdWeMv/ and peruse the code if you like.

Also, i think this is the actual resource i used for the structure of the promise chaining https://scotch.io/tutorials/javascript-promises-for-dummies -its the one resource i could make actual sense of which applicable to what i was trying to do.

cheers
-RockLobster7