Skip to content

Instantly share code, notes, and snippets.

@SavinaRoja
Last active July 28, 2023 20:29
Show Gist options
  • Save SavinaRoja/a434844c51cc62b3e3b86addad58f13e to your computer and use it in GitHub Desktop.
Save SavinaRoja/a434844c51cc62b3e3b86addad58f13e to your computer and use it in GitHub Desktop.
// Code sample demonstrating use of Rust-style Result for an API Service in Angular + Typescript
// Posted: 2023-07-24
// Paul Barton
// Released to the public domain
import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';
import {
HttpClient,
HttpErrorResponse,
HttpParams,
HttpResponse,
} from '@angular/common/http';
import { catchError, map, Observable, of } from 'rxjs';
export enum ResultType {
Ok,
Err,
}
export type Ok<T> = {
type: ResultType.Ok;
value: T;
};
export type Err<E> = {
type: ResultType.Err;
error: E;
};
export type Result<T, E> = Ok<T> | Err<E>;
export enum CreateUserError {
EmailAlreadyExists,
Other,
}
export interface NewUser {
email: string;
name: string;
age: number;
}
export interface User {
id: number;
email: string;
name: string;
age: number;
}
@Injectable()
export class ApiService {
constructor(private http: HttpClient) {}
createUser(newUser: NewUser): Observable<Result<User, CreateUserError>> {
const uri = environment.backend_uri + `users/create`;
return this.http.post<any>(uri, newUser, { observe: 'response' })
.pipe(
// This handles the conversion from HttpResponse to Result.
// It needs to come before the catchError.
map((data: HttpResponse<any>): Ok<User> => {
return { type: ResultType.Ok, value: data.body };
})
)
.pipe(
// This should be the last thing to happen in the pipeline
catchError(
(
err: HttpErrorResponse,
caught: Observable<any>
): Observable<Err<CreateUserError>> => {
if (err.status === 400 && err.error.detail === 'Invalid email') {
return of<Err<CreateUserError>>(
{
type: ResultType.Err,
error: CreateUserError.EmailAreadyExists,
}
)
} else {
return of<Err<CreateUserError>>(
{
type: ResultType.Err,
error: CreateUserError.Other,
}
)
}
}
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment