0
votes

I'm making an Angular Application which is sending calls to API. This is one of methods from AuthService (responsible for authenticating user):

login(loginForm: UserLoginRequest): Observable<AuthenticationResponse | TfaResponse> {
    return this.http.post<AuthenticationResponse | TfaResponse>('api/auth/login', loginForm);
}

This methods return an Observable with one of following responses:

export class AuthenticationResponse {
    token: string;
    refreshToken: string;
}

export class TfaResponse {
    requiresTwoFactor: boolean;
    isTwoFactorConfigured: boolean;
}

Then I subscribe on this Observable in my component and I want to do different actions in dependence of type of response:

this.authService.login(userLoginForm)
    .subscribe(
      (result) => {
        // type of result is AuthenticationResponse
        if (*type check*) {
            // action with AuthenticationResponse
        }
        // type of result is TfaResponse
        else if (*type check*) {
            // action with TfaResponse
        }
      },
    );

At the moment I'm just checking if object owns some properties from this class, like this:

this.authService.login(userLoginForm)
        .subscribe(
          (result) => {
            if ('token' in result) {
                // action with AuthenticationResponse
            }
            else if ('requiresTwoFactor' in result) {
                // action with TfaResponse
            }
          },
        );

But I understand that's a definitely bad solution which will broke up after first change in AuthenticationResponse or TfaResponse class. How should I check class in this case?

1
Typescript "types" don't exist at runtime, and you are not actually creating class instances, just plain JS objects. You will need something in your response to determine what type it is, weather thats an additional property value, or you are checking the properties the server sent back (like you are doing now). - cjd82187
why does your service return two totally different objects? Your underlying issue is this flaky contract - Liam
if ('token' in result) seems like a perfectly acceptable solution to me? Though you shoukd really be using hasOwnProperty not in - Liam

1 Answers

0
votes

You can use instanceof keyword to check types.

if (result instanceof AuthenticationResponse) {
  .....
} else if (result instanceof TfaResponse) {
  .....
}