Search code examples
javascriptangulartypescripthttppost

HttpClient in Angular request does not start


Introduction: A button in a form invokes a method named methodForm in the component. methodForm in turn calls a method named methodService in the service layer. methodService should make an HTTP POST call. Issue: The HTTP POST call is not happening. methodService is still invoked, as confirmed by a console.log. Question: Why is the HTTP POST call not being executed? What could be the reasons and possible solutions? Additional Information: I attempted to typecast the Observable with interfaces type. I tried using the JSONPlaceholder APIs, but without success. I am using standalone Angular components.

register.component.html

<button
            class="w-100 btn btn-primary btn-lg"
            (click)="register()"
            [disabled]="form.invalid && form.submitted">
            Continua la registrazione
          </button>
          <div class="mt-2 text-center">
          <small 
            *ngIf="form.submitted && form.invalid"
            class="form-text text-danger">Il form non è valido. Controlla i campi
          </small>
        </div>

register.component.ts:

export class RegisterComponent implements OnInit {
  @ViewChild('form') form!: NgForm;
  grantValue!: number;
  grantUser: number = 2;
  grantClient: number = 3;
  private __genericUser: GenericUser = new GenericUser;
  italianProvinces: string[] = [...];
  selectedProvince: string = '';
  maxDate!: string;

  ngOnInit(): void {
    this.genericUser.gender = "";
    this.genericUser.grant = 0;
    this.genericUser.province = "";
    const today = new Date();
    const year = today.getFullYear();
    const month = ('0' + (today.getMonth() + 1)).slice(-2);
    const day = ('0' + today.getDate()).slice(-2);
    this.maxDate = `${year}-${month}-${day}`;
  }

  constructor( private service: RegisterService, private router: Router){
  }

  set genericUser(genericiUser: GenericUser){
    this.__genericUser = genericiUser;
  }
  get genericUser(): GenericUser {
    return this.__genericUser;
  }
  
  register(): void {
   if(this.form.invalid){
      this.service.register(this.__genericUser);
    } else {
      this.router.navigateByUrl('');
    }
    }
}

register.service.ts:

@Injectable({
  providedIn: 'root'
})
export class RegisterService{
  apiurl = environment.API_URL_REGISTER_USER;
  api = 'https://jsonplaceholder.typicode.com/posts'
  constructor(private http: HttpClient) {}

  register(__genericUser: GenericUser): Observable<GenericUser> {
    console.log("stop");
    return this.http
      .post<GenericUser>(this.apiurl, __genericUser)
      .pipe(map((resp) => resp));
  }
}

app.config.ts:

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes), provideHttpClient()],
};

Solution

  • The service method returns an observable that you need to subscribe to. In your component change as follows:

    this.service.register(this.__genericUser).subscribe(); // added subscribe()
    

    And in the service you can add the operator take to complete and avoid memory leaks. Like this:

    return this.http
          .post<GenericUser>(this.apiurl, __genericUser)
          .pipe(take(1), map((resp) => resp));