Angular 2 call setInterval() undefined Services form Dependency injection
Asked Answered
T

3

27

I want to call a function every 10 minutes by using setInterval() and in this function I want to use a Service (called auth) that I get from the Dependency Injector of Angular 2, the problem is that the console tells me following:

EXCEPTION: TypeError: this.auth is undefined

  constructor(private auth: AuthService){
    setInterval(function(){ this.auth.refreshToken(); }, 1000 * 60 * 10);
  }
Trask answered 6/3, 2016 at 15:36 Comment(1)
setInterval(() => this.auth.refreshToken(), 1000 * 60 * 10);Auburta
C
76

this in the function given to setInterval doesn't point to the class when it is called.

Use arrow function instead.

 constructor(private auth: AuthService){
    setInterval(() => { this.auth.refreshToken(); }, 1000 * 60 * 10);
  }
Conditioning answered 6/3, 2016 at 15:53 Comment(2)
Excellent post on the subject here : 2ality.com/2012/04/arrow-functions.htmlExtensor
I tried setInterval(() => this.auth.refreshToken(), 1000 * 60 * 10); and it used to failed but for some reason your line of code worked - thanksInsurer
A
8

A full discussion of this issue can be found in the documentation for the setInterval() method, captioned The "this" Problem. About halfway down the page.

The jist is that it is the result of a change in the "this" variable. The function being passed into the setInterval() function is extracted from the class context and placed into the context of setInterval() (the window). So, it is undefined.

There are several solutions to this issue. The method proposed by toskv above is a fairly common approach. Another solution is to use the bind() method.

constructor(private auth: AuthService) {
    setInterval(this.auth.refreshToken.bind(this), 1000 * 60 * 10);
}

Reference material from this question, answer by Pointy.

Documentation for the bind() method.

A good article on javascript scope, which can still come back to bite you in typescript.

Agglomeration answered 30/11, 2016 at 9:42 Comment(2)
Using Angular and had an issue with this. Used bind and instantly worked! TY!Brannon
Great answer! Thanks for the links too.Pitiable
P
0

There's a little trick for solving that. Hope this helps.

First do

const this1 = this;

then

constructor(private auth: AuthService) {
    setInterval(this1.auth.refreshToken.bind(this), 1000 * 60 * 10);
}
Pyotr answered 25/8, 2017 at 9:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.