5tar-Kaster
5tar-Kaster

Reputation: 908

Angular 8 httpclient code running out of order

I am trying to load content from files in an assets folder using Angulars HttpClientModule. However it looks like when the WebService.webCall method is run, everything in the method runs in the wrong order. I have created a stackblitz code sample here to demonstrate the issue I am having, https://stackblitz.com/edit/angular-avuhul.

The code works 100% as it should, except for the methods returning with empty strings and a little bit later the data from the file gets loaded, but its always after the method is already returned, too late for me to do any logic on the contents of the file.

I am not sure what is causing this and everywhere I look in stackoverflow I see references to older versions of Angular. I assume this is why those solutions didn't work with my problem.

Upvotes: 1

Views: 104

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

will the previous answer meant to solve the problem by return an observable and subscribe at the component level and move any next step to the subscribe body when the data available, async/await can do the same result but without that much of changes

WebService

just convert the observable to promise and change the return type

  getConfigFile(url: string): Promise<string> {
    return this.webGet(url, "[1] - ");
  }
  getContentsFile(url: string): Promise<string> {
    return this.webGet(url, "[2] - ");
  }

 webGet(url: string, prefix: string): Promise<string> {
    //log the start of the web call
    this.log(prefix + "(001) run webGet [" + url + "]");

    //create the headers
    const headers = new HttpHeaders().set(
      "Content-Type", "text/plain; charset=utf-8"
    );

    //create the result
    var result: string = "";

    // 👇 run the http Get method
    return  this.http.get(url, { headers, responseType: "text" }).toPromise();
  }

component

just prefix reloadConfig and reloadFile with async keyword , and prefix getContentsFile , getConfigFile with await keyword

// 👇 web call method
  async reloadConfig() {
    console.clear();
    console.log("===================");

    // 👇 testing with a config json file
    this.config = await this._web.getConfigFile("/assets/config.json");
    this.log("loaded config data: " + this.config);

    //check if the file loaded
    if (this.config.length > 0){
      //apply some logic to the config file
      this.modified = "config file contains [" + this.config.length + "] chars";
    } else {
      this.log("config data is empty");
    }
  }

  //👇 web call method
  async reloadFile() {
    console.clear();
    console.log("===================");

    // 👇 testing with a blank file containing text
    this.contents = await this._web.getContentsFile("/assets/filewithcontents");
    this.log("loaded contents data: " + this.config);

    //check if the file loaded
    if (this.contents.length > 0){
      //apply some logic to the config file
      this.modified = "contents file contains [" + this.contents.length + "] chars";
    } else {
      this.log("contents data is empty");
    }
  }

demo 🚀

Upvotes: 1

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

http.get call is asynchrony call at the time you just subscribe webGet method will return the result so to fix this you need to update the service webGet to return the observable then you can subscribe at the component this will be a better way than handle the subscription at the service level.

webGet(url: string, prefix: string) {
    //log the start of the web call
    this.log(prefix + "(001) run webGet [" + url + "]");

    //create the headers
    const headers = new HttpHeaders().set(
      "Content-Type", "text/plain; charset=utf-8"
    );

    //create the result
    var result: string = "";

    return this.http.get(url, { headers, responseType: "text" })

  }

demo 🎉

Upvotes: 1

Related Questions