How to send post request to properly using Http Client in Angular
I want to create a registration page that holds email, username, first-name, last-name and password. I am using Angular 13 as front-end and Django as back-end. The forms works perfect but I am getting an error on the console.
- here is my registration form:
[![enter image description here][1]][1]
- here is the error on the console:
x> Access to XMLHttpRequest at 'http://127.0.0.1:2000/auth/users/' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
x>http-error-handler.service.ts:41
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: 'Unknown Error', url: 'http://127.0.0.1:2000/auth/users/', ok: false, …}
(anonymous) @ http-error-handler.service.ts:41
(anonymous) @ catchError.js:10
OperatorSubscriber._error @ OperatorSubscriber.js:23
error @ Subscriber.js:40
_error @ Subscriber.js:64
error @ Subscriber.js:40
_error @ Subscriber.js:64
error @ Subscriber.js:40
_error @ Subscriber.js:64
error @ Subscriber.js:40
onError @ http.mjs:1849
invokeTask @ zone.js:406
onInvokeTask @ core.mjs:25574
invokeTask @ zone.js:405
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1648
globalCallback @ zone.js:1679
globalZoneAwareCallback @ zone.js:1712
error (async)
customScheduleGlobal @ zone.js:1796
scheduleTask @ zone.js:393
onScheduleTask @ zone.js:283
scheduleTask @ zone.js:386
scheduleTask @ zone.js:221
scheduleEventTask @ zone.js:247
(anonymous) @ zone.js:1951
(anonymous) @ http.mjs:1902
_trySubscribe @ Observable.js:37
(anonymous) @ Observable.js:31
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
doInnerSub @ mergeInternals.js:19
outerNext @ mergeInternals.js:14
OperatorSubscriber._next @ OperatorSubscriber.js:13
next @ Subscriber.js:31
(anonymous) @ innerFrom.js:51
_trySubscribe @ Observable.js:37
(anonymous) @ Observable.js:31
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
mergeInternals @ mergeInternals.js:50
(anonymous) @ mergeMap.js:13
(anonymous) @ lift.js:10
(anonymous) @ Observable.js:26
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
(anonymous) @ filter.js:6
(anonymous) @ lift.js:10
(anonymous) @ Observable.js:26
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
(anonymous) @ map.js:6
(anonymous) @ lift.js:10
(anonymous) @ Observable.js:26
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
(anonymous) @ catchError.js:9
(anonymous) @ lift.js:10
(anonymous) @ Observable.js:26
errorContext @ errorContext.js:19
subscribe @ Observable.js:22
onSubmit @ researcher-signup.component.ts:57
ResearcherSignupComponent_Template_form_ngSubmit_4_listener @ researcher-signup.component.html:7
executeListenerWithErrorHandling @ core.mjs:15014
wrapListenerIn_markDirtyAndPreventDefault @ core.mjs:15052
next @ Subscriber.js:91
_next @ Subscriber.js:60
next @ Subscriber.js:31
(anonymous) @ Subject.js:34
errorContext @ errorContext.js:19
next @ Subject.js:27
emit @ core.mjs:22462
onSubmit @ forms.mjs:5450
FormGroupDirective_submit_HostBindingHandler @ forms.mjs:5532
executeListenerWithErrorHandling @ core.mjs:15014
wrapListenerIn_markDirtyAndPreventDefault @ core.mjs:15052
(anonymous) @ platform-browser.mjs:466
invokeTask @ zone.js:406
onInvokeTask @ core.mjs:25574
invokeTask @ zone.js:405
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1648
globalCallback @ zone.js:1679
globalZoneAwareCallback @ zone.js:1712
Show 55 more frames
researcher-signup.component.ts:57 {email: 'sdaf@gmail.com', username: 'test123', first_name: 'test', last_name: 'test', password: 'jodfjadmfa'}
x> zone.js:2680 POST http://127.0.0.1:2000/auth/users/ net::ERR_FAILED
- here is the list of services I wrote: 1. code for auth.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { ResearcherData } from './../models/researcher-data.interface';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { HandleError, HttpErrorHandler } from './http-error-handler.service';
import { HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'my-auth-token'
})
};
@Injectable({
providedIn: 'root'
})
export class AuthService {
private url = 'http://127.0.0.1:2000/auth/users/';
private handleError: HandleError;
constructor(
private http: HttpClient,
httpErrorHandler: HttpErrorHandler,
) {
this.handleError = httpErrorHandler.createHandleError('AuthService');
}
/** register researcher to the server */
register(researcherdata: ResearcherData): Observable<ResearcherData>{
return this.http.post<ResearcherData>(this.url, researcherdata,httpOptions)
.pipe(
catchError(this.handleError('register', researcherdata))
)}
}
- code for http-error-handler.service.ts
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';
/** Type of the handleError function returned by HttpErrorHandler.createHandleError */
export type HandleError =
<T> (operation?: string, result?: T) => (error: HttpErrorResponse) => Observable<T>;
/** Handles HttpClient errors */
@Injectable({
providedIn: 'root'
})
export class HttpErrorHandler {
constructor(private messageService: MessageService) { }
/** Create curried handleError function that already knows the service name */
createHandleError = (serviceName = '') =>
<T>(operation = 'operation', result = {} as T) =>
this.handleError(serviceName, operation, result);
/**
* Returns a function that handles Http operation failures.
* This error handler lets the app continue to run as if no error occurred.
*
* @param serviceName = name of the data service that attempted the operation
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
handleError<T>(serviceName = '', operation = 'operation', result = {} as T) {
return (error: HttpErrorResponse): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
const message = (error.error instanceof ErrorEvent) ?
error.error.message :
`server returned code ${error.status} with body "${error.error}"`;
// TODO: better job of transforming error for user consumption
this.messageService.add(`${serviceName}: ${operation} failed: ${message}`);
// Let the app keep running by returning a safe result.
return of( result );
};
}
}
- code for message.service.ts:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class MessageService { messages: string[] = []; add(message: string) { this.messages.push(message); } clear() { this.messages = []; } }
-here is code for researcher-data.interface.ts: ``` export interface ResearcherData{
email: "",
username: "",
first_name: "",
last_name: "",
password: ""
}
```
- here is code for researcher-signup.component.ts:
import { AuthService } from './../../../core/services/auth.service'; import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms' @Component({ selector: 'researcher-signup', templateUrl: './researcher-signup.component.html', styleUrls: ['./researcher-signup.component.css'] }) export class ResearcherSignupComponent implements OnInit { forms: FormGroup; constructor( private fb: FormBuilder, private authService: AuthService ) { } ngOnInit(): void { this.forms = this.fb.group({ email: ['', [Validators.required, Validators.email]], username: ['', [Validators.required]], first_name: ['', [Validators.required, Validators.maxLength]], last_name: ['', [Validators.required]], password: ['', [Validators.required, Validators.maxLength]], }); } get email() { return this.forms.get('email'); } get password() { return this.forms.get('password'); } get username() { return this.forms.get('username'); } get first_name() { return this.forms.get('first_name'); } get last_name() { return this.forms.get('last_name'); } onSubmit() { // console.log(this.forms.value,this.forms.valid); this.authService.register(this.forms.value) .subscribe(result => console.log(result)) } }
- here is Django Rest page on http://localhost:2000/auth/users/ :
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/izKZb.jpg