Home > Mobile >  Set logic in one Observable? Angular
Set logic in one Observable? Angular

Time:10-30

When I send a form which is not valid, it is sent to me 2 times http post request.

<form [formGroup]="formG" (submit)="onSubmitForm()">
 <input type="text formControlName="userName">
 <button type="submit">
</form>

inside ts

   onSubmitForm() { 
    this.service.addUserName(this.formG.value).subscribe((res:any) => {
      console.log('succes response');
    }) 
  }

inside service:

  public addUserName(userName) { 
    return this.httpClient.httpPostGlobal<any[]>(`addNewUser/${userName}`, null);
  }

httpPost is a little complicated. Made as a global service.

inside global service for httpPostGlobal is ->

public httpPostGlobal<T>(path: string, data: any): Observable<HttpResponse<T>> {

    let postMetodData = (observer: Observer<HttpResponse<T>>) => {
        this.getTokenFromServiceData().subscribe(
            userToken => {
                let httpOptions = {
                    observe: 'response' as 'response',
                    headers: new HttpHeaders({
                        Authorization: ,
                        accept: 'application/json'
                    }),
                };

                this.http.post<T>(environment.url   path, data, httpOptions)
                    .pipe(
                        catchError((err: HttpErrorResponse) => {
                            return throwError(err);
                        }))
                    .subscribe(
                        response => this.successCallback(response, observer),
                        (error: HttpErrorResponse) => this.errorCallback(error, observer)
                    );
            }
        );
    };

    let obs = new Observable<HttpResponse<T>>(postMetodData);
    return obs;
}

Inside this function is problem... probably catchError but i don't know.

The only problem is that it duplicates http request post 2 times. Everything else works. When added and when the response is 200 or 201 and everything else works. The only problem is when the form that is not valid is submitted and when the backend returns 422, it fires the same request 2 times and if I pressed submit only once on the form.

successCallback is only:

private successCallback<T>(response: HttpResponse<T>, observer: Observer<HttpResponse<T>>): void {
    if ((response.status === 200 || response.status === 204 || response.status === 201) &&
        (response.statusText === HttpService.OK || response.statusText === HttpService.NO_CONTENT
            || response.statusText === HttpService.CREATED)) {
        observer.next(response);
    } else {
        observer.error(response);
    }

    observer.complete();
}

CodePudding user response:

There are few strange things here:

  1. Authorization: , This is empty?
  2. errorCallback is called but we do not see the implementation?

Looking just at your code, i would say that the only scenario when 2 api calls are posted to a server is when

this.http.post<T>(environment.url   path, data, httpOptions)

is called twice. You can add a console.log(1) just before to see how many times is printed.

If that is a case then probably you have a value on stream:

this.getTokenFromServiceData()

that comes "again" when some call has failed.

CodePudding user response:

You are subscribing to multiple events here, regardless of if the first one works or not. Instead you should put this logic into one Observable.

I also fix some issues, and used some typescript to clean things up.

public httpPostGlobal<T>(path: string, data: any): Observable<HttpResponse<T>> {
  return this.getTokenFromServiceData().pipe(
    switchMap(userToken => {
      const httpOptions = {
        observe: 'response' as 'response', // this probably isnt needed as this is already the default value
        headers: new HttpHeaders({
          Authorization: `${userToken}`,
          accept: 'application/json',  // this probably isnt needed as this is already the default value
        }),
      };
      return this.http.post<T>(`${environment.url}${path}`, data, httpOptions);
    }),
    map(response => this.successCallback(response, observer)),
    catchError((err: HttpErrorResponse) => this.errorCallback(error, observer)),
  );
}
  • Related