Angular6 returns the result after subscribing to an HTTP POST request

Currently, I am in the process of learning angular and attempting to create a component that allows users to register through my web API.

Within my component, the code on form submission looks like this:

 onSubmit(contactFormRef: NgForm) {
    const result = this.usersService.CreateUser(this.registerDto);
    contactFormRef.reset();
  }

The UsersService contains the following method:

 CreateUser(dto: UserCreateDto): boolean {
    const endpoint = ApiQueryService.ApiEndpoint + this.postUserEndpoint;
    let result: any;

    let d = new Date(dto.birthDate.year, dto.birthDate.month - 1, dto.birthDate.day);
    dto.userDto.birthDate = d.toJSON();
    const password = dto.password;
    this.client.post(endpoint, dto.userDto).subscribe(x =>
    {
      result = x;
      const registerDto: RegisterDto = {Password: password, UserId: result};
      const registerResult = this.authService.RegisterUser(registerDto);
      return registerResult;
    });

    return false;
  }

and the AuthService contains the following method:

 RegisterUser(dto: RegisterDto): boolean {
    let isSuccess: boolean = false;
    const endpoint = ApiQueryService.ApiEndpoint + this.registerEndpoint;
    this.client.post(endpoint, dto, {observe: 'response'}).subscribe(response => {
      isSuccess = response.status === 200;
      return isSuccess;
    });
    return isSuccess;
  }

My issue arises from wanting to return the isSuccess variable from this line of code within the component:

this.client.post(endpoint, dto, {observe: 'response'}).subscribe(response => {
      isSuccess = response.status === 200;
      return isSuccess;
    });

I aim to handle the result in the component based on whether it is successful or not. However, due to the asynchronous nature of subscribing, the component always receives a false result. This dilemma is hindering the functionality I desire.

https://i.sstatic.net/KYo2L.png

Answer №1

A method to achieve this is by utilizing pipe map() within the AuthService, returning the necessary data, handling it in the UserService, returning a boolean value once again, and subscribing in the component. This setup ensures that both services will return Observable<boolean>

AuthService:

RegisterUser(dto: RegisterDto): Observable<boolean> {
    const endpoint = ApiQueryService.ApiEndpoint + this.registerEndpoint;
    return this.client.post(endpoint, dto, {observe: 'response'})
    .pipe(
        map(response => response.status === 200),
    );
}

UserService:

CreateUser(dto: UserCreateDto): Observable<boolean> {
    const endpoint = ApiQueryService.ApiEndpoint + this.postUserEndpoint;
    let result: any;
    let d = new Date(dto.birthDate.year, dto.birthDate.month - 1, dto.birthDate.day);
    dto.userDto.birthDate = d.toJSON();
    const password = dto.password;
    return this.client.post(endpoint, dto.userDto).pipe(
        switchMap(result => {
            const registerDto: RegisterDto = {Password: password, UserId: result};
            return this.authService.RegisterUser(registerDto);
        }),
    );
}

Component:

onSubmit(contactFormRef: NgForm) {
    this.usersService.CreateUser(this.registerDto).pipe(take(1))
        .subscribe(result => {
            // Perform necessary actions and then reset the form
            contactFormRef.reset();
        });
}

This process involves passing data from the AuthService through the UserService before finally subscribing in the component at the end.

Answer №2

When using the this.client.post method, it is important to note that it is asynchronous. This means that any code below this method will execute before the response is received. To ensure that the isSuccess variable is set correctly, you can modify the code to return

this.client.post.subscribe(response => {...})

 UpdateUser(dto: UpdateDto): boolean {
    let isSuccess: boolean = false;
    const endpoint = ApiQueryService.ApiEndpoint + this.updateEndpoint;
    return this.client.post(endpoint, dto, {observe: 'response'}).subscribe(response => {
      isSuccess = response.status === 200;
      return isSuccess;
    });

  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on verifying if a variable is a tuple in TypeScript

I am attempting to determine if a variable passed to a function, which can either be an array of numbers or an array of tuples, is the array of tuples. function (times: Array<number> | Array<[number, number]>) { if (Array.isArray(times[0]) ...

Error: Unable to connect to 'ngbTypeahead' as it is not recognized as a valid attribute of 'input' in the template

Having trouble with ngbTypeahead. The console is displaying the following error message: Error: Template parse errors: Can't bind to 'ngbTypeahead' since it isn't a known property of 'input'. (" <inpu ...

mat-slider: experiencing delay in updating while dragging it

Incorporating @angular/material in my Angular 5 application has been quite the journey. The specific version of Angular Material that I have implemented is 5.0.2, along with @angular/animations 5.1.2. My usage of the slider component is rather straightfor ...

The functionality of d3 transition is currently non-existent

I've encountered an issue with my D3 code. const hexagon = this.hexagonSVG.append('path') .attr('id', 'active') .attr('d', lineGenerator(<any>hexagonData)) .attr('stroke', 'url(#gradi ...

What is the best way to organize the data retrieved from the api into a map?

In my search page component, I display the search results based on the user's query input. Here is the code snippet: "use client"; import { useSearchParams } from "next/navigation"; import useFetch from "../hooks/useFetch&qu ...

Where does tsc retrieve its definitions from when utilizing npm definitions?

After transitioning from using typings to just relying on npm, I noticed that the @types directory in node_modules is present, but there are no additional files required. Previously with typings, I always had to include the index.d.ts file within the typi ...

Personalized context hook TypeScript

I have been experimenting with a custom hook and the context API, based on an interesting approach that I found in this repository. However, I encountered an error when trying to use it with a simple state for a number. Even though I wanted to create a mo ...

Can NgZone be utilized within a shared service instance?

I am currently working on creating an injectable singleton service for my application that will provide all components with information about the window width and height, as well as notify them when the page is scrolled or resized. Below is the code snipp ...

Eliminate elements from an array using a specific key for filtering

My Array is called MainArray MainArray=[{ {First Name: "First Name"}, {Last Name: "Contact"}, {Last Name: "Contact"} ] I am trying to trim the key-value pair from this array like this: if (key == 'First Name') { del ...

Bypass React Query execution when the parameter is null

I am facing an issue with a react query problem. I have a separate file containing all the queries: const useFetchApTableQuery = (date: string): UseQueryResult => { const axiosClient = axios.create() const fetchApTableQuery = async (): Promise<A ...

Angular2 Navigation Menu

I have a side bar and I want its children to appear when the user clicks on the parent. For example, clicking on LinkTest should display its corresponding content as block. You can check out the Angular and Typescript code snippet at this link: http://jsfi ...

What techniques can I use to adjust the size of an image through zooming in and out?

In my custom gallery component, the crucial code section looks like this: <Gallery> <Header> <img src={galleryIcon} alt='Galley icon' /> <h1>My Gallery</h1> </Header> ...

Changing a d3 event from JavaScript to Typescript in an Angular2 environment

I am a beginner in Typescript and Angular 2. My goal is to create an Angular2 component that incorporates a d3js tool click here. However, I am facing challenges when it comes to converting it to Typescript. For instance, I am unsure if this code rewrite ...

All components load successfully except for the worker in Webpack

I've been working on configuring webpack to bundle my react project. I successfully set up the webpack_public_path variable and all modules are loading correctly, except for the worker. const path = require('path'); const MonacoWebpackPlugi ...

Immutable parameter in constructor

While analyzing some TypeScript code, I stumbled upon a peculiar declaration within a class definition: constructor(readonly constructorParam : Type) { // no assignment of constructorParam here } Surprisingly, constructorParam is still being used as usu ...

"Angular SwtAlert2: The Ultimate Multi-Selection Tool

I am trying to integrate the ng-select directive into SweetAlert2, but the code snippet below is not working as expected: const { value: formValues } = await swal.fire({ title: 'Multiple inputs', html: '<ng-select id=" ...

The TypeScript compiler is attempting to fetch node modules in the browser while compiling a single output file

After setting up my tsconfig file to build a frontend typescript application with a single output structure, I encountered an unexpected issue: { "compilerOptions": { "target": "es5", "module": "system", "lib": [ "e ...

Effectively enhance constructor by incorporating decorators

Is it possible to properly extend a class constructor with decorators while maintaining the original class name and static attributes and methods? Upon reading the handbook, there is a note that cautions about this scenario: https://www.typescriptlang.or ...

Angular 2: Retrieving the Currently Active Tab from a Bootstrap Tab Using TypeScript

Using a basic bootstrap tab, I am looking to identify the active tab in order to perform a function in my .ts file. Below is the code snippet: <li role="presentation" class="active"> <a href="#daily" aria-controls="daily" role="tab" data-toggl ...

"Patience is a virtue with the RXJS WaitUntil

I am currently facing a challenge in my Angular application with ngrx and rxjs operators. I need to implement a solution where I can wait for a specific ngrx selector to return data before proceeding further. Within my notification effects, I have a scena ...