0

I'm going through Angular's tutorial at https://angular.io/tutorial/toh-pt6 and I've got a couple of questions. My second question is very close to one asked here about the same Angular demo, but though it almost gets to my specific syntax question, it falls just short, and the one response doesn't get into it.

Retrieving data from a service from an Observable returned by a call to HttpClient.get, they have a catchError operator in the pipe:

/** GET heroes from the server */
getHeroes(): Observable<Hero[]> {
  return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      tap(_ => this.log('fetched heroes')),
      catchError(this.handleError<Hero[]>('getHeroes', []))
    );
}

This much I understand. I'd expect this.handleError to return a handler, a mapping of an error to code that handles the error. A little further up on the page they've already provided this:

private handleError<T>(operation = 'operation', result?: T) {
  return (error: any): Observable<T> => {

    // TODO: send the error to remote logging infrastructure
    console.error(error); // log to console instead

    // TODO: better job of transforming error for user consumption
    this.log(`${operation} failed: ${error.message}`);

    // Let the app keep running by returning an empty result.
    return of(result as T);
  };
}

First, I notice that though these examples are heavily typed, this one appears not to type the returned value. I was expecting

private handleError<T>(operation = 'operation', result?: T) **: some type** {

Second, I think what the function is returning is the lambda expression mapping Observable<T> to the large block of code between braces (which itself ultimately returns result, the safe default value we want to be returned to the subscriber in the event of an error so it can continue processing, wrapped in an Observable with of). But I don't understand the syntax on the second line before the lambda expression:

  return (error: any): Observable<T> => {

What is return (error: any):, positioned here just inside the definition of the handleError function, and how does it relate to what follows it? What is the syntactic significance of the second colon? What relationship between the expressions on either side of it does it represent?

Green Grasso Holm
  • 468
  • 1
  • 4
  • 18

1 Answers1

0

I figured it out. But this is one of the most confusing syntax details I've ever encountered. If it had been written

return (error: any) => { ...

I would have recognized it as mapping something called error to whatever is returned by the code between the opening brace and its matching closing brace. It specifies that error can be anything, and says nothing about the type of the value expected to be returned by the code between the braces.

The insertion of : Observable<T>,

  return (error: any): Observable<T> => {

is the arrow function counterpart of : string in this function definition:

function foo(x: any) : string { /* code that must return a string */ }

It means what's returned from the code between the braces must be an Observable<T>.

Green Grasso Holm
  • 468
  • 1
  • 4
  • 18
  • `handleError` just returns an arrow function (thats what lambda functions are called in typescript) that takes `error: any` as parameter, does some stuff (logging in this example) and then returns a safe value (empty array of type T in this case). If you are familiar with something like `const foo = (arg: any): someType => { ... return x as someType; };`, that is essentially the same. – Gunnar B. Dec 11 '20 at 22:40