1

I'm trying to use the setInterval() function in order to change text to the user every 3 seconds.

I tried looping with for loop but that doesn't work - I see the 'test 03' and that's it.

I can't find a solution.

export class MessagesComponent implements OnInit {
  items = ['test 01', 'test 02', 'test 03'];
  currentItem: any;
  private interval;

  constructor() {}

  ngOnInit() {
    for (let i = 0; i < this.items.length; i++) {
      this.interval = setInterval(() => {
        this.currentItem = this.items[i];
      }, 3000);
    }
  }
}
{{ currentItem }}

Appreciate any help!

0

3 Answers 3

3

Try it this way instead.

pointer points to the current content you want to display. With each interval pointer gets increased by 1 until it has a value > 2. Then it starts with 0 again.

export class MessagesComponent implements OnInit {
  items = ['test 01', 'test 02', 'test 03'];
  currentItem: any;
  private pointer: number = 0;

  constructor() {}

  ngOnInit() {
      this.interval = setInterval(() => {
        this.currentItem = this.items[this.pointer];
        this.pointer++;
        if (this.pointer > 2) { this.pointer = 0 };
      }, 3000);
  }

}
Sign up to request clarification or add additional context in comments.

3 Comments

Why was this answer voted down? May the person who did this please state the nature of his or her problem with my answer.
thanks a lot! how can i make the change be more smooth? like fade effect or something like that? @Lynx 242
You're welcome. To achieve fading effects plain interpolation won't work. This is usually done with CSS using, for example, 2 overlapping labels. And while the one label fades out the other fades in. But I have no example at hand I could give you. Sorry.
1

Try this:

export class MessagesComponent implements OnInit {
  items = ['test 01', 'test 02', 'test 03'];
  currentItem: any;
  private interval;

  constructor() {}

  ngOnInit() {
    for (let i = 0; i < this.items.length; i++) {
      this.interval = setInterval(() => {
        this.currentItem = this.items[i];
      }, 3000 * i);
    }
  }
}
{{ currentItem }}

Comments

1

If you are happy with rxjs,

import { timer } from 'rxjs';
import { tap } from 'rxjs/operators';

ngOnInit() {
  timer(0, 3000)
    .pipe(
      tap(v => {
        this.currentItem = this.items[v%3]
      })
    )
    .subscribe(console.log);
}

less code, no loop, no fancy logic involved :)

You can do even better with

export class MessagesComponent implements OnInit {
  private timer$ = timer(0, 3000);
  ngOnInit() {
    // for loop can be completely removed
  } 
}

and in html, use

{{ items[(timer$ | async) % 3] }}

so you literally just use 1 line of code to do the same thing by leveraging async pipe and rxjs, and forget about the ugly for-loop.

demo https://stackblitz.com/edit/angular-m5prrk?file=src%2Fapp%2Fapp.component.ts

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.