SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Getting a value from a function within setTimeout

    I'm new to JS and I have recently ran into a problem with the setTimeout function while using the Jquery-UI Datepicker.

    I would like to get a value from within a function referenced in a setTimeout function and use that value on other areas of my code. However, because setTimeout delays the code execution, I can't seem to assign and use the said value.

    Here's part of the code
    Code:
    $calendar.datepicker({
        inline: true,
        onSelect: function (dateText,inst) {
            var startDate;
            window.setTimeout(function(){getStartDate();}, 1);
    
            // ... Do something with startDate. No matter how I try, startDate is always undefined. 
    
            function getStartDate () {
                var r = $calendar
                    .find('.ui-datepicker-current-day')
                        .parent()
                            .find('.selectable')
                            .first()
                                .children()
                                .text();
    
                startDate = new Date(date.setDate(r));
                return startDate;
    
            }
        },
    });
    I am basically trying to build a datepicker that allows users to select a 3 day package from the datepicker that is predefined.

    Basically the logic flows like this:
    1. Users will select which 3 days they would like (Tue, Wed, Thurs) for example.
    2. Datepicker will show all possible selectable periods in the month.
    3. users can click on any of the 3 day (Tue, Wed or Thurs), and datepicker will register Tue as the first day and Thurs as the last day.

    Datepicker only registers clicks in the onSelect handler for some reason and it has to use the setTimeout function, or the registered click is the previous click. On the same note, I can't try to set a click handler on the datepicker as datepicker doesn't register any click events that happen on selectable areas if defined from elsewhere.

    Hence,

    I need to use the setTimeout function otherwise the value returned from Jquery UI datepicker is wrong.

    Ideally, I'm looking for startDate to be the value returned from the function getStartDate() that is set within the timeout function.

    What I'm writing is obviously wrong and I have no idea how to return the startDate value from within the timeout function and use it elsewhere

    Help is very much appreciated. Thanks!

  2. #2
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would like to get a value from within a function referenced in a setTimeout function and use that value on other areas of my code. However, because setTimeout delays the code execution, I can't seem to assign and use the said value.
    I have a variable in my program called:

    Code:
    var winning_lottery_number;
    In one week's time, that variable will be assigned the winning lottery numbers for the PowerBall Jackpot after the numbers are published on the lottery website. The thing is I would like to use that value now so that I can buy the winning lottery ticket. How do I do that?

  3. #3
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,117
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    Hi,

    It's not a silly question.

    You're trying to rely on the what's in the HTML to get the dates, it looks like onSelect is firing before the HTML has changed(class="selectable" added) so you're using setTimeout to wait a moment so that the HTML is updated before your code is run.

    Using timeout's like this is always a pain as you're always fighting for the correct orders, so I'd suggest using jQuery's API for the datepicker.

    dateText already has the selected date, you can get todays date with new Date(), in the code you'll already need to have the 3day ranges.
    I'd just find which range the selected date falls in.

    But it's possible one of the other callbacks like onClose will fire after the HTML is updated which might allow your current code to work.

    Hope it helps

  4. #4
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 7stud View Post
    I have a variable in my program called:

    Code:
    var winning_lottery_number;
    In one week's time, that variable will be assigned the winning lottery numbers for the PowerBall Jackpot after the numbers are published on the lottery website. The thing is I would like to use that value now so that I can buy the winning lottery ticket. How do I do that?
    Hey Stud,

    That's a real sarcastic way of saying its not possible. But I appreciate the effort put into the reply. Simply speaking its impossible yes?

    Quote Originally Posted by markbrown4 View Post
    Hi,

    It's not a silly question.

    You're trying to rely on the what's in the HTML to get the dates, it looks like onSelect is firing before the HTML has changed(class="selectable" added) so you're using setTimeout to wait a moment so that the HTML is updated before your code is run.

    Using timeout's like this is always a pain as you're always fighting for the correct orders, so I'd suggest using jQuery's API for the datepicker.

    dateText already has the selected date, you can get todays date with new Date(), in the code you'll already need to have the 3day ranges.
    I'd just find which range the selected date falls in.

    But it's possible one of the other callbacks like onClose will fire after the HTML is updated which might allow your current code to work.

    Hope it helps
    Hey Mark,

    Thanks for the reply.

    The problem here is that onSelect fires before the date can be retrieved with jQuery traversing.

    Lets say I have 2 date ranges and I did not setTimeout:

    1 Jul - 3 Jul (option 1)
    8 Jul - 10 Jul. (option 2)

    1st click: Option 1. Results: startDate: 1Jul.
    2nd click: Option 2. Results: startDate: 1Jul.
    3rd click: Option 1. Results: startDate: 8Jul.

    In this case, the result if I did not use setTimeout always gets the previous value that was clicked. If I used setTimeout however, the value is correct.

    If I were to fix the code with the onSelect Handler, I can try the method you suggested about finding which dates the range falls into. Problem is that date range is determined by the datepicker. (I've only set specific dates to disable, and I have no idea how to test with this date range).

    Do you have any idea how to?

    I do have one other method that I'm thinking about though.

    1. Get the current day, Create a loop to -1day from current day and test of the new date is disabled. If disabled, return the last enabled day.

    Problem with this approach: I have no idea how to test for disabled days

    I have never thought of the onClose handler. It might work. I'll give it a try as soon as I have the time to look closer at the onClose API.

  5. #5
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Pity, I just realized I will not be able to use onClose because I'm using a inline datepicker

  6. #6
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Simply speaking its impossible yes?
    It is certainly impossible to get a value from a function that hasn't executed yet. Nothing inside a function exists until the function executes. It doesn't matter if the function executes 1 micro second from now or in a hundred thousand years--no assignments inside the function nor any mathematical operations inside the function nor any function calls inside the function will occur until the function executes. Here is an example:

    Code:
    function do_stuff() {
    
       console.log(x/0);
    
    }
    That function has two errors in it: x does not exist, and there is a division by 0. But if you put that function definition in a script and run it, js won't report any errors. js will only report the errors when you execute the function.

    This code:

    Code:
            var startDate;
            window.setTimeout(function(){getStartDate();}, 1);
    
            // ... Do something with startDate. No matter how I try, startDate is always undefined. 
    
            function getStartDate() {
                  startDate = 10;
            }
    ...is similar to telling js to assign the value 10 to startDate in 100,000 years, and then trying to log the value of startDate now. The problem is that startDate will be undefined for the next 100,000 years. It's not until the setTimeout function executes that startDate will be assigned a value.

  7. #7
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,117
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    Hi,

    The easiest way is just to move the logic into the setTimeout function.
    Code javascript:
    function getStartDate () {
      var r = $calendar
        .find('.ui-datepicker-current-day')
        .parent()
        .find('.selectable')
        .first()
        .children()
        .text();
     
      return new Date(date.setDate(r));
    }
     
    $calendar.datepicker({
      inline: true,
      onSelect: function (dateText,inst) {
        window.setTimeout(function(){
          startDate = getStartDate();
          // Do something with startDate. 
        }, 1);
      }
    });

  8. #8
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 7stud View Post
    It is certainly impossible to get a value from a function that hasn't executed yet. Nothing inside a function exists until the function executes. It doesn't matter if the function executes 1 micro second from now or in a hundred thousand years--no assignments inside the function nor any mathematical operations inside the function nor any function calls inside the function will occur until the function executes. Here is an example:

    Code:
    function do_stuff() {
    
       console.log(x/0);
    
    }
    That function has two errors in it: x does not exist, and there is a division by 0. But if you put that function definition in a script and run it, js won't report any errors. js will only report the errors when you execute the function.

    This code:

    Code:
            var startDate;
            window.setTimeout(function(){getStartDate();}, 1);
    
            // ... Do something with startDate. No matter how I try, startDate is always undefined. 
    
            function getStartDate() {
                  startDate = 10;
            }
    ...is similar to telling js to assign the value 10 to startDate in 100,000 years, and then trying to log the value of startDate now. The problem is that startDate will be undefined for the next 100,000 years. It's not until the setTimeout function executes that startDate will be assigned a value.
    That clears things up. Thanks.

    The issue I'm trying to solve now is that I can assign the value to startDate after 1ms, but I would like to ensure that later processes get the correct startDate. To make things a little clearer, startDate will be used when the user submits a form. By then, 1ms would already have passed and startDate should be assigned. How do I ensure that the startDate value is updated when the user submits the form?

    Thanks.

  9. #9
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by markbrown4 View Post
    Hi,

    The easiest way is just to move the logic into the setTimeout function.
    Code javascript:
    function getStartDate () {
      var r = $calendar
        .find('.ui-datepicker-current-day')
        .parent()
        .find('.selectable')
        .first()
        .children()
        .text();
     
      return new Date(date.setDate(r));
    }
     
    $calendar.datepicker({
      inline: true,
      onSelect: function (dateText,inst) {
        window.setTimeout(function(){
          startDate = getStartDate();
          // Do something with startDate. 
        }, 1);
      }
    });
    This looks similar to what I'm doing as an alternative right now. (I set 2 timeout functions instead. Your code is definitely cleaner). However, I wouldn't be able to pass on the values from startDate into another function later in the program since everything is within the setTimeout function.

    The problem I'm having is as the reply above. The issue I'm trying to solve now is that I can assign the value to startDate after 1ms, but I would like to ensure that later processes get the correct startDate. To make things a little clearer, startDate will be used when the user submits a form. By then, 1ms should already have passed and startDate should be assigned. How do I ensure that the startDate value is updated when the user submits the form?

  10. #10
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How do I ensure that the startDate value is updated when the user submits the form?
    Why is it that this startDate variable is necessary at all? You can get and set any values you need in the onsubmit event handler, although I have no idea why you need to set or get any values at all. Why does submitting the form fail to send the proper date to the server?

  11. #11
    SitePoint Enthusiast
    Join Date
    Apr 2013
    Location
    Singapore
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great one 7stud, I was so immersed in the timeout function problem that I totally forgot I can attach a submit handler on the form. Got my problems solved now. Thanks!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •