2
votes

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.

5
Don't subscribe in service. Subscribe in component. - Roberto Zvjerković
Usually services don't execute logic. The common thing is to return the Subscription from the service and subscribe in the component. I know you sayd that is not what you're looking for. But a workaround could be to use a variable in the service that is setted to true or false when the subscribtion in the service return something. In the component do a setTimetout that every n milliseconds check if the variable is not undefined. When it has a value, you know the service has finished its job. But meh, I don't think is a good way. - Jacopo Sciampi
^*return the Observable from the service* - Jota.Toledo
Op can you be more specific about what is the stuff that you want to do? - Jota.Toledo

5 Answers

2
votes

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();
});
0
votes

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

0
votes

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

  }
}
0
votes

simply use of operator:

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

I think Async and Await is what you are looking for, How To Use Async and Await