简体   繁体   中英

Return Observable from http Post

I am working on a sample app, where I have a Login Component, which calls authentication service. The service in turns makes an Http call, and based on the response of the call, I need to do something.

In the service, I am using http Post along with subscribe to do stuff when my user is able to login, however, I want my component function to consume this response from my manipulation and proceed accordingly.

Below is the code: Login Component:

this.authService.login(this.userName, this.password)

Authentication Service

 return this.http.post('http://localhost:8080/login',{
  "username": userName,
  "password": password
}).subscribe(data => {
   //some stuff
  return true;
  }, () => return false;
})

I want my LoginComponent to wait till it receives true or false from the service.

One way to do this will be just to return the http call back to component and write whole logic there, but that is not what I am looking forward to. I was hoping if there is a better way to do this.

You can write

import { Observable } from 'rxjs/internal/Observable';

and

return new Observable((subscriber) => {
    this.http.post('http://localhost:8080/login', {
        userName,
        password,
    }).subscribe(data => {
        //some stuff
        subscriber.next(true);
    }, () => subscriber.error();
});

Try to return the observable into your login component and subscribe there. Then you can do what you want if the request succeded

Maybe you can try this:

Service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()

export class AuthService {
  constructor (private client:HttpClient) { }

  logIn(userName:string, password:string):Observable<boolean> {
    return (this.client.post('myUrl', {'userName': userName,'pwd':password}).pipe(
      map(resp => {
        // perform logic
        const allowed:boolean = resp['authenticated'];
        return allowed;
      })
    ));
  }

}

Component

import { Observable } from 'rxjs';
import { AuthService } from './auth.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  name = 'Angular';
  constructor(private authSvc:AuthService) { }
  authObservable$:Observable<boolean>;
  ngOnInit() {
    this.authObservable$ = this.authSvc.login('myUser', 'myPwd');

    // can use authObservable$ in template with async pipe or subscribe

  }
}

Use RxJS Operators for your Service logic and return the modified Observable from your Service.

import { tap, map, catchError } from 'rxjs/operators';

login(userName: string, password: string): Observable<boolean> {
  return this.http.post('http://localhost:8080/login', { userName, password })
    .pipe(
      tap(data => doSideEffects(data)), // do side effects
      map(data => true), // modify the data and return the value you care for
      catchError(error => of(false)) // return an Observable with the value that should be returned on errors
    );
}

Always subscribe in your Components.

this.authService.login(this.userName, this.password)
  .subscribe(value => /* value will be true on success and false on errors */);
// the error callback will be never executed here as you caught the error with catchError 
// in the Service an returned a default value for errors there

simply use of operator:

import { of } from 'rxjs';
return this.http.post('...url..', payload).subscribe(data => {
   //some stuff
  return of(true);
  }, () => return of(false);
})

我认为Async 和 Await是您正在寻找的, 如何使用 Async 和 Await

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM