Skip to content

Instantly share code, notes, and snippets.

@touhidrahman
Created January 20, 2022 22:17
Show Gist options
  • Select an option

  • Save touhidrahman/23fed8523ef56b4dfcf54267d3fe4d64 to your computer and use it in GitHub Desktop.

Select an option

Save touhidrahman/23fed8523ef56b4dfcf54267d3fe4d64 to your computer and use it in GitHub Desktop.
AbstractFormService in Angular
import { FormBuilder, FormControl, FormGroup } from '@angular/forms'
import { Observable, throwError } from 'rxjs'
export abstract class AbstractFormService<T, InputT extends { id?: string }> {
form: FormGroup
constructor(protected fb: FormBuilder) {
this.form = this.buildForm()
}
get valid(): boolean {
if (this.form.untouched) return false
return this.form.valid
}
getFormValue(): InputT {
return this.form.value
}
setFormValue(dto: InputT | null): void {
if (!dto) {
this.form.reset()
return
}
this.form.reset(dto)
if (dto.id) {
const control = new FormControl(dto.id)
this.form.addControl('id', control)
}
}
abstract buildForm(): FormGroup
abstract loadFromApiAndFillForm$(id: string): Observable<T>
save$(): Observable<T> {
if (this.form.invalid) return throwError(() => new Error('Invalid form'))
const id = this.form.get('id')?.value ?? null
return id ? this.update$(id) : this.create$()
}
protected abstract create$(): Observable<T>
protected abstract update$(id: string): Observable<T>
}
@Injectable()
export class MovieCreateFormService extends AbstractFormService<Movie, MovieCreateInput> {
constructor(protected override fb: FormBuilder, private movieService: MovieService) {
super(fb)
}
buildForm(): FormGroup {
return this.fb.group({
name: ['', Validators.required],
releaseYear: '',
genre: '',
})
}
loadFromApiAndFillForm$(id: string): Observable<Movie> {
return this.movieService
.findById(id)
.pipe(tap((data) => this.setFormValue(data)))
}
protected create$(): Observable<Movie> {
return this.movieService
.create(this.getFormValue())
.pipe(tap(() => this.form.reset()))
}
protected update$(id: string): Observable<Movie> {
return this.movieService
.update(id, this.getFormValue())
.pipe(tap(() => this.form.reset()))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment