Sammy
Sammy

Reputation: 3697

Handling Error Thrown by Observable

The following HTML/JS reads countries from a local JSON files and provides the list to a dropdown:

export interface Country {
  code: string;
  name: string;
}

@Injectable()
export class CountriesService {
  private url = '/assets/data/countries.json';

  constructor(private http: Http) {}

  getCountries(): Observable < Country[] > {
    return this.http.get(this.url)
      .map(res => res.json())
      .catch(err => {
        console.log(err);
        return Observable.throw(err);
      });
  }
}
<select class="form-control custom-select" formControlName="country">
					<option value="" disabled selected hidden translate>Select Country</option>
					<option *ngFor="let country of countries$ | async" value="{{country.code}}">{{country.name}}</option>
				</select>

What happens if an error is thrown in the getCountries() function, where am I supposed to catch it and display a user-friendly message?

Note: I'm using the async pipe in the component HTML

Upvotes: 1

Views: 93

Answers (1)

Igor
Igor

Reputation: 62298

You can handle it in the catch block at the point you subscribe to getCountries. Example: Add a new component field named fatalErrorMessage and populate that in the catch and display it in your template if there is a value using *ngIf="fatalErrorMessage". What you do or display depends on your requirements.

I made a guess on the logic of your component.

fatalError:string = null;
ngOnInit(){
    this.countries$ = this.countryService.getCountries().catch(err => {
        console.log(err);
        this.fatalError = "Countries could not be loaded";
        return Observable.of([]); // return empty array
      });
}

Template code:

<p *ngIf="fatalError">An unexpected error has occurred: {{fatalError}}</p>
<select class="form-control custom-select" formControlName="country">
    <option value="" disabled selected hidden translate>Select Country</option>
    <option *ngFor="let country of countries$ | async" value="{{country.code}}">{{country.name}}</option>
</select>

Upvotes: 1

Related Questions