0

In my html I have:

<img src="{{activeImage}}" class="img-fluid img-file img-center-style">

In the .ts, activeImage is defined with a default value:

  promotions: any = [];
  activeImage: string = 'assets/Promo_1.jpg';

Now in the ngOnInit method I call a service which returns the following and sets it in promotions: enter image description here

What is my goal:

To change the activeImage to the value of file in commercial_file array. (It always has one element - 0). Then after a period of time, it changes the value to the second file in array.

Here is what I tried:

  ngOnInit() {
    this.mainService.getPromotion().subscribe(promotions => {
      console.log("getPromotion from servise are ", promotions);
      this.promotions = promotions;

      //If there is something, call method setActiveImage and send array
      if (this.promotions.length > 0) {
        this.setActiveImage(this.promotions);
      }

    });

  }

  setActiveImage(promotions) {
    for (let i = 0; i <= promotions.length - 1; i++) {
      console.log("one promotion is: ", promotions[i]);
      setTimeout(function () {
      //SET SRC TO FILE FROM PROMOTIONS
        this.activeImage = 'http://myurl.com/public/Commercials/' + promotions[i].commercial_file[0].file;
      }, 3000);

    }
  }

The img src should have file value for 3s, then change to the second image value. But that does not happen, it just shows the default value defined at the beginning (assets/Promo_1.jpg).

Now if I set this in ngOnInit without any setTimeout or anything, it works fine and it sets the picture well:

this.activeImage = 'http://myurl/public/Commercials/' + this.promotions[0].commercial_file[0].file;

StackBlitz: https://stackblitz.com/edit/angular-5fteig?file=src%2Fapp%2Fapp.component.ts

TLDR: Change img src on 3s with data gathered from server.

IkePr
  • 900
  • 4
  • 18
  • 44

1 Answers1

3

use arrow function or bind this to the function if you need to access this

setTimeout(()=> {
    //SET SRC TO FILE FROM PROMOTIONS
    this.activeImage = 'http://myurl.com/public/Commercials/' + promotions[i].commercial_file[0].file;
}, 3000);

Also in your example, you need get instance of service in your constructor before using it, and import it as well if your editor doesn't does that automatically.

constructor(private mainService : mainService){}

Edit:

To change images every 3 seconds set timer with incremental values:

setActiveImage(promotions) {
    for (let i = 0; i <= promotions.length - 1; i++) {
      console.log("one promotion is: ", promotions[i]);
      setTimeout( ()=> {
      //SET SRC TO FILE FROM PROMOTIONS
        this.activeImage = 'http://myurl.com/public/Commercials/' + promotions[i].commercial_file[0].file;
      }, 3000*(i+1)); //Change i+1 to i if you don't want delay for 1st image.
    }
}
Shub
  • 2,686
  • 17
  • 26
  • I did set it in the constructor, I just didn't write it here. Your solution works and its set the picture but only to the second value. It doesn't show the first file value, then 3s later changes to second value. It immediately shows the second value. :) – IkePr Jan 26 '20 at 14:35
  • @IkePr thats because all the timeouts run at once, please check the edit in answer. – Shub Jan 26 '20 at 15:22
  • This works ! Can you please elaborate a bit more how does this work by incrementil the value with i ? – IkePr Jan 26 '20 at 21:36
  • For 1st case value of i+1 will be 1 so 3000*1= 3000 or 3 sec, for second it will be 2*3s similarly for 3rd it will be 3*3s and so on.. – Shub Jan 27 '20 at 06:27
  • Thank you so much @Shubanker, I marked as correct answer. Now I have a different problem with this solution. When I set the timer (3000) as a custom variable, the time gets mixed up a lot. Example: 4000*(i), then i is 0. Second iteration, 3000*(i), then it is 3s OK. Third iteration 4000*(i) then is 2... Do you have any idea what's happening or should I open a new thread ? – IkePr Jan 27 '20 at 11:15
  • @IkePr your problem is unclear with your statement, either edit your question with details and your updated code or better open a new thread. – Shub Jan 27 '20 at 13:54
  • I opened a new thread https://stackoverflow.com/questions/59930695/typescript-settimeout-custom-time-from-variable-that-is-dynamic-in-for-loop/59930929#59930929 – IkePr Jan 27 '20 at 15:27