Search code examples
javascriptember.jsember-simple-auth

setTimeout doesn’t work


I am working with Ember-Simple-Auth to authenticate my App against a remote server which serves me an API token which must be refreshed every 30 mins through the use of a renew token. To that aim I included an async call to ember-Simple-Auth restore method which implements the token refreshing, which should trigger every 25 minutes using setTimeout. However, of the three calls to setTimeout, only one works properly although to me they all look to be the same. May you by any chance be able to help me on this matter ?

Sample code :

export default Base.extend({
   restore(data) {
     console.log("restoring");
     var renewDelay = 30000; //set to 30 seconds for testing purpose
     var expirates = data.expirates * 1000;  //server response lists expiration as a unix timestamp in seconds
     var current = new Date().getTime();

     if (expirates < current) {
       console.log("token expired " + expirates + " " + current);
       return Ember.RSVP.reject();
     } else {
       if (expirates - current > renewDelay / 4) {
         console.log("token valid " + expirates + " " + current + ", renew in " + Number(expirates - current - 30000));
         //this one works as expected after 30s
         setTimeout(this.restore, expirates - current - renewDelay, data); 
         return Ember.RSVP.resolve(data);
       } else {
         console.log("token valid " + expirates + " " + current + ", renewing now");
         return Ember.$.ajax({
           method: "GET",
           url: "/renew",
           accepts: 'application/json',
           headers: {
             Authorization: data.renew_token
           }
         })
         .then(function(data) {
           console.log("next renew in " + Number((data.expirates * 1000) - current - renewDelay));
           //this one is never called
           setTimeout(this.restore, (data.expirates * 1000) - current- renewDelay, data); 
           return data;
         });
       },
     },
   authenticate(identification, password) {
   console.log("authenticating");
   return Ember.$.ajax({
    method: "POST",
    url: "/auth",
     contentType: 'application/json',
     accepts: 'application/json',
     data: JSON.stringify({ username: identification, password: password })
   })
   .then(function(data) {
     console.log("next renew in " + Number((data.expirates * 1000) - new Date().getTime() - 30000));
      //this one is not triggered either
     setTimeout(this.restore, (data.expirates * 1000) - new Date().getTime() - 30000, data);
     return data;
   });
 }
});

Solution

  • Your this.restore inside both callbacks probably could refer to wrong this, causing the restore function to never get called. Have you tried debugging what this refers to? Using arrow callbacks could fix this problem, like

    .then((data) => {
        ...
        setTimeout(this.restore, (data.expirates * 1000) - new Date().getTime() - 30000, data);
    
    });