Sleeping with TypeScript

0

Good afternoon, I'm having to make the typescript excute a call every 10 milliseconds. I have a search using setInterval but the information comes as undefined but when I save it, the values in this.tags.name come as undefined.

export class InicialComponent implements OnInit {

  tagsMongoUrl = 'http://localhost:8080/tags';
  tags = [];
  tagsSave = new Tags();
  msgs: Message[] = [];
  nome = '';
  valor = '';

  constructor(private principalService: PrincipalService, private http: Http) { }

  ngOnInit() {
    this.pesquisar();
  }

  pesquisar() {
    this.principalService.pesquisar()
      .then(() => null);
  }

  salvar() {

    setInterval(function () {
      const v = 100;

      for (let i = 0; i < v; i++) {
        this.tagsSave.name = 'name ' + i;//undefined aqui pois não acessa o objeto
        this.tagsSave.value = i.toString();
        this.nome = this.tagsSave.name;
        this.valor = this.tagsSave.value;
        console.log(this.valor);

        this.saveData();
      }
    }, 3000);
  }


  saveData() {
    const headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return this.http.post(this.tagsMongoUrl,
      JSON.stringify(this.tagsSave), { headers })
      .toPromise()
      .then(response => response.json());
  }

}
    
asked by anonymous 05.11.2018 / 17:53

1 answer

0

The problem is that when you use setInterval , anonymous function passes, and within anonymous functions the scope changes, and this now refers to the anonymous function, not the method of its class.

To solve this you have three options:

  • Arrow function .
  • salvar() {
    
      setInterval(() => {
        const v = 100;
    
        for (let i = 0; i < v; i++) {
          this.tagsSave.name = 'name ' + i; //undefined aqui pois não acessa o objeto
          this.tagsSave.value = i.toString();
          this.nome = this.tagsSave.name;
          this.valor = this.tagsSave.value;
          console.log(this.valor);
    
          this.saveData();
        }
      }, 3000);
    }

    Explanation : arrow functions has no scope, so this continues to refer to the external scope of the function.

  • Variable referring to this created in top function.
  • salvar() {
      let $that = this;
      setInterval(function() {
        const v = 100;
    
        for (let i = 0; i < v; i++) {
          $that.tagsSave.name = 'name ' + i; //undefined aqui pois não acessa o objeto
          $that.tagsSave.value = i.toString();
          $that.nome = $that.tagsSave.name;
          $that.valor = $that.tagsSave.value;
          console.log($that.valor);
    
          $that.saveData();
        }
      }, 3000);
    }

    Explanation: The anonymous function can access the variable $that , which is a reference to this of the external function.

  • Use bind in the anonymous function.
  • salvar() {
    
      setInterval(function() {
        const v = 100;
    
        for (let i = 0; i < v; i++) {
          this.tagsSave.name = 'name ' + i; //undefined aqui pois não acessa o objeto
          this.tagsSave.value = i.toString();
          this.nome = this.tagsSave.name;
          this.valor = this.tagsSave.value;
          console.log(this.valor);
    
          this.saveData();
        }
      }.bind(this), //<-- aqui
      3000);
    }

    Explanation: The first argument of the bind method tells the function what the this variable will represent in its context.

    The most modern and correct option would be the second, with arrow functions. I recommend using it.

        
    05.11.2018 / 18:05