1

I have the following code that is not working correctly.

I have a service, which offers registration for a user.

register(firstname: string, lastname: string, email: string, password: string): Observable<boolean> {
    let body = {firstname: firstname, lastname: lastname, email: email, password: password};
    
    this.http.post(this.base_url + "api/register/user/", body)
    .subscribe(
        (data) => {
            if((data as any).status == 'success') {
                return Observable.of(true);
            }
        },
        (error) => {
           return Observable.of(false);
    });
    return Observable.of(false);
  }

The register method is working correctly since the API where I'm registering the users is returning "success". The problem is when I'm calling it as follows:

registerUser(e) {
    
    ...
    
    let isRegistered = false;
    
    this.userService.register(firstname, lastname, email, password).subscribe(register => isRegistered = register);
    
    
    if(isRegistered) {
        console.log("isRegistered = true");
        this.router.navigate(['/home']);
        return true;
    } else {
        console.log("isRegistered = false");
        return false;
    }
  }

I'm also importing the necessary modules:

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

"isRegister" is remaining false and as a result, the page is not redirecting to the home page.

Does anyone have an idea where the problem could be?

Thank you in advance!

Ahmet Emre Kilinc
  • 5,489
  • 12
  • 30
  • 42
UrmLmn
  • 1,099
  • 2
  • 16
  • 28

1 Answers1

6

The isRegistered value will always be false because you are treating an asynchronous operation like a synchronous one. Basically the check if (isRegistered) will run before you have acquired the value from your service. In order to avoid this, you have to move the checks inside of the subscription success callback:

this.userService
  .register(firstname, lastname, email, password)
  .subscribe(isRegistered => {
    if (isRegistered) {
      this.router.navigate(["/home"]);
      return true;
    } else {
      return false;
    }
  });

In this way you will be sure that isRegistered's value has been set by the result of the service call.

Your register() function also has a flaw - you will always return an Observable of false. You probably want to return the result of the HTTP request. You should .map() the result of the HTTP response to a Boolean and subscribe when using the service.

register(firstname: string, lastname: string, email: string, password: string): Observable<boolean> {
  const body = { firstname, lastname, email, password };

  return this.http.post(this.base_url + 'api/register/user/', body)
    .map(data => {
        if((data as any).status === 'success') {
            return Observable.of(true);
        } else {
            return Observable.of(false);
        }
    })
    .catch(() => Observable.of(false));
}
Tsvetan Ganev
  • 8,246
  • 4
  • 26
  • 43
  • Thank you for your answer! I'm having another problem with this approach now, the http is not making any request inside the service. I'm getting the following error: "Http failure response for (unknown url): 0 Unknown Error". – UrmLmn Jan 16 '18 at 13:26
  • The error cannot be caused by my changes, since I didn't change the parameters passed to the service in any way. Can you share more of the `registerUser()` code? Also check this answer: https://stackoverflow.com/questions/47180634/i-get-http-failure-response-for-unknown-url-0-unknown-error-instead-of-actu - you might have CORS issues. – Tsvetan Ganev Jan 16 '18 at 13:41
  • The registerUser() method only takes the email, password, ... from the html. Can you please take a look at the register() method of the UserService that I've posted above. Do you now any better way on how I could make the http post request or is the method fine? – UrmLmn Jan 16 '18 at 13:45
  • I made an edit because I spotted a flaw in your `register()` function. However, the HTTP call looks correct. The only thing I can think of is if the `this.base_url` value is an invalid URL. Can you please share it? – Tsvetan Ganev Jan 16 '18 at 13:51
  • The base url is as follows: private base_url = "http://localhost:5001/"; . I also made the change in the register() method, but I'm getting the following error now: " Type 'Subscription' is not assignable to type 'Observable'." – UrmLmn Jan 16 '18 at 13:55
  • Oops, I've forgotten to change the `.subscribe()` to `.map()`. I've re-written the whole function body. Please check if it works now. – Tsvetan Ganev Jan 16 '18 at 14:16
  • 1
    You are probably having the server on a different port than the Angular app served by `ng serve`. If that is the case, I'm sure this is a CORS issue since for the browser `localhost:5001` and `localhost:{OTHER_PORT}` are different origins no matter these are on the same machine. – Tsvetan Ganev Jan 16 '18 at 14:23
  • You are right, it is a CORS problem :/ I'm having them inside two docker containers and they have different ports. The server is running in Slim PHP. Thank you for your answers man ;) – UrmLmn Jan 16 '18 at 14:34