I'm working on a application that uses gitLab Issues to display a chart. To authenticate with the api I want to use a access token that gets appended to the get request like that:
https://gitlab.de/api/v4/issues?private_token=************
I have a form where the user enters the personal access token. I want to validate the token with a custom input validator and add a error message below the input field (I'm using material angular).
I use a service to make the http requests:
private makeGetRequest(endpoint: string, params: HttpParams) {
return this.http.get<Issue[]>(this.buildURL(endpoint), {params}).pipe(catchError(this.handleError));
}
public getIssues(): Observable<Issue[]> {
let params = new HttpParams().set('private_token', this.access_token);
return this.makeGetRequest('/issues', params)
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// Return an observable with a user-facing error message.
return throwError(
'Something bad happened; please try again later.');
}
In the component I added a validator function. I'm trying to make some call to the api and then check if it worked.
// Form group with validation
authForm = new FormGroup({
url: new FormControl('gitlab.de'),
token: new FormControl('', [this.validateToken])
});
// Add error message below input fields
getErrorMessage() {
if (this.authForm.controls.token.hasError('required')) {
return 'You must enter a token';
}
return this.authForm.controls.token.hasError('tokenInvalid') ? 'Not a valid token' : '';
}
// Check if token is valid using api
validateToken(control: AbstractControl): { [key: string]: any } | null {
if (control.dirty || control.touched) {
this.apiService.getIssues().subscribe((response) => {}, (error) => {return {'tokenInvalid': true}})
} else {
return null
}
}
There are several tutorials but I can't wrap my head around them. When I type something in the input I just get this output in console: ERROR TypeError: this is undefined
The validator function is executed by Angular and not our code which is the reason why the 'this' keyword inside your validator function does not point to your class.
You can simply bind your validateToken function in the Validators array like this:
Also, I would recommend you to use custom async validator function if you are performing async operations in your validator function like this by returning a promise/observable: