-1

In my Angular Projekt I have this Code:

  ngOnInit() {

    var countTo = 50;
    for (let i = 1; i < (countTo + 1); i++) {
      this.http.get('https://projekt-dunkelbunt.de/index.php/wp-json/wp/v2/media?max_page=25&page=' + i).subscribe(data =>{

        for(let key in data){
            if(data.hasOwnProperty(key)){
              this.media.push(data[key]);
              console.log(this.media);
              this.descriptions.push(data[key].description.rendered.split('>', 7));
              console.log(this.descriptions);
            }
        }

        console.log("AFTER FOR Length: " + this.media.length);

        if (this.media.length != (this.counter * 10)) {
          this.execute = false;
        }

        this.counter++;

      }, error => {
        console.error("Fehler  beim Laden: " + i + " - " + error);
        i = countTo + 1;
        this.loadPictures();
      });
    }   

    inializeDefaultButtons();

    console.log("ngOnInit(bilder.component.ts) -> done!");
  }

My Problem with this Code is, that the for gets executed AFTER the inializeDefaultButtons() and I dont know why, I need the Data from the FOR in the inializeDefaultButtons() Method, but right know the inializeDefaultButtons() Method gets executed and after that the for gets executed.

What am I doing wrong?

yama_HD
  • 480
  • 1
  • 4
  • 14
  • "I don't know why", simply because it's an asynchronous operation. You ask to do something (like an API call), it takes some time. In the mean time, the code carries on, so the thread isn't blocked. Whenever the API call comes back, the callback function is executed. Welcome to the wonderful world of asynchronism. – Jeremy Thille Jan 11 '21 at 13:00
  • Also you are making 50 simultaneous calls to `projekt-dunkelbunt.de`, not sure the server will like this. You'll probably get banned or denied. – Jeremy Thille Jan 11 '21 at 13:02
  • Is there a way to make the call Synchronously? – yama_HD Jan 11 '21 at 13:02
  • 1
    No. And anyway you _really_ don't want to do this. Don't think "Asynchronism is a pain, I want to find a way to do things synchronously". Worse mistake ever, because you will be blocking your threrad and freezing your site and your server. Learn and embrace asynchronism. – Jeremy Thille Jan 11 '21 at 13:04
  • Yeah but First I need to get the Data and when I have the Data i need to do something with it. In my Asynchronous Code, its doing something with the data ander then gettnig the data, there is something wrong i guess – yama_HD Jan 11 '21 at 13:11
  • 1
    I have marked your question as a duplicate (as not understanding asynchronism is a very, very, VERY, VEEEEERRRRYYYYY common question), please visit the link above – Jeremy Thille Jan 11 '21 at 13:15

2 Answers2

0

Javasript has a well known asynchrounous behaviour. Try to put your inializeDefaultButtons() inside your subscribe first callback (right after your for .. in loop ) and it will be invoked when the loop is done.

 this.http.get('https://projekt-dunkelbunt.de/index.php/wp-json/wp/v2/media?max_page=25&page=' + i).subscribe(data =>{

        for(let key in data){
            if(data.hasOwnProperty(key)){
              this.media.push(data[key]);
              console.log(this.media);
              this.descriptions.push(data[key].description.rendered.split('>', 7));
              console.log(this.descriptions);
            }
        }

        console.log("AFTER FOR Length: " + this.media.length);

        inializeDefaultButtons(); // <-- here


        if (this.media.length != (this.counter * 10)) {
          this.execute = false;
        }

        this.counter++;

      }, error => {
        console.error("Fehler  beim Laden: " + i + " - " + error);
        i = countTo + 1;
        this.loadPictures();
      });
    }   

The reason is that JS merely doesn't wait the end of execution for an unknown time-to-execute event (Http response in your case), so it makes your implemented code in stand-by, till a response is retrieved from the backend service, at this stage, it gets back to the code-to-exectue inside the data's callback and start its execution.

SeleM
  • 9,310
  • 5
  • 32
  • 51
  • Higher order operators would make things really clean in this scenario, It's sad to see OP is not utilising wonderful features provided by RXJS https://medium.com/angular-in-depth/practical-rxjs-in-the-wild-requests-with-concatmap-vs-mergemap-vs-forkjoin-11e5b2efe293 – Vikas Jan 11 '21 at 12:51
  • 1
    @Vikas Agree, seems he/she's new to JS. Introducing such terms in an early stage could mess it up IMHO. Thanks tho – SeleM Jan 11 '21 at 12:55
  • Agree with u too :) – Vikas Jan 12 '21 at 07:10
0

What are you trying to achieve ?

You can create observables without subscribing to them for each and then binding all obserevable into concat operator if their order is to be kept.

https://rxjs-dev.firebaseapp.com/api/index/function/concat