1

I have a component's method, but it has some unexpected behavior:

private fetchExternalStyleSheet(outerHTML: string): string[] {
  let externalStyleSheetText: string;
  let match: RegExpExecArray;

  const matchedHrefs = [];
  while (match = this.hrefReg.exec(outerHTML)) {
    matchedHrefs.push(match[1]);
  }
  const requestedUrl = this.url + matchedHrefs[0];
  this._ApiService.makeRequest(requestedUrl, ActionType.content)
    .subscribe((response: any) => {
      externalStyleSheetText = response.content;
      console.log('inside subscribe', externalStyleSheetText); // => expected content
  });
  console.log('outside subscribe', externalStyleSheetText); // => undefined

  return this.parseStyleSheetText(externalStyleSheetText);
}

inside .subscribe method externalStyleSheetText binding has expected value, while outside it gives me undefined. I suppose it related with async behavior of subscribe method. I reviewed some related issues but still it is unsolved, because of the fact that everybody suggests make request via subscribe in ngOnInit lifecycle hook and it means that we get request result before component initialization. But in my case I have to make it outside ngOnInit, so I get undefined

a_zatula
  • 438
  • 1
  • 3
  • 19

1 Answers1

1

To solve it, I suppose you have to make fetchExternalStyleSheet return an observable, and subscribe to it from the outside call. So fetchExternalStyleSheet will look something like this:

private fetchExternalStyleSheet(outerHTML: string): Observable<string[]> {
    let externalStyleSheetText: string;
    let match: RegExpExecArray;

    const matchedHrefs = [];
    while (match = this.hrefReg.exec(outerHTML)) {
      matchedHrefs.push(match[1]);
    }
    const requestedUrl = this.url + matchedHrefs[0];
    return this._ApiService.makeRequest(requestedUrl, ActionType.content)
      .pipe(map((response: any) => {
        externalStyleSheetText = response.content;
        return this.parseStyleSheetText(externalStyleSheetText);
      }));
  }

and in the call, you subscribe to the result, like this:

callerMethod() {
    this.fetchExternalStyleSheet('<h1>Test</h1>').subscribe(response => {
      this.parsedStylesheet = response;
    })
  }

I made a stackblitz, where clicking a button calls callerMethod: https://stackblitz.com/edit/angular-tpogff

ShamPooSham
  • 2,301
  • 2
  • 19
  • 28