Search code examples
angulartypescriptauthenticationangular8mean-stack

Property 'token' does not exist on type 'Object' - Angular 8


I am watching MEAN Stack - Mean Auth App Tutorial in Angular 2, since I am new to Angular and I'm using Angular 8, some of the codes is deprecated due to the new updates. So I have this code and I don't know how to fix it.

This is my working code in Auth.service.ts

There are no errors in this codes

    authenticateUser(user){
    let headers = new HttpHeaders();
    headers.append('Content-Type','application/json');
    return this.http.post('http://localhost:3000/users/authenticate', user,{headers: headers})
  }

  storeUserData(token, user){
    localStorage.setItem('id_token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authToken = token;
    this.user = user;
  }

  logout(){
    this.authToken = null;
    this.user = null;
    localStorage.clear();
  }

In my login.component.ts, there's an error showing

Property 'token' does not exist on type 'Object

Property 'user' does not exist on type 'Object

Property 'msg' does not exist on type 'Object

This is my login.component.ts code

onLoginSubmit(){
    const user = {
      username: this.username,
      password: this.password
    }

    this.authService.authenticateUser(user).subscribe(data => {
      if(data){
        this.authService.storeUserData(data.token, data.user);
        this.flashMessage.show('You are now logged in', {
          cssClass: 'alert-success',
          timeout: 5000});
        this.router.navigate(['dashboard']);
      } else {
        this.flashMessage.show(data.msg, {
          cssClass: 'alert-danger',
          timeout: 5000});
        this.router.navigate(['login']);
      }
    });
  }

login.components.ts file If I put wrong login credentials, It's logging in.

 onLoginSubmit(){
    const user = {
      username: this.username,
      password: this.password
    }

    this.authService.authenticateUser(user).subscribe(data => {
      console.log(data);
      if(user){
        this.authService.storeUserData(data.token, data.user);
        this.flashMessage.show('You are now logged in', {
          cssClass: 'alert-success',
          timeout: 5000});
        this.router.navigate(['dashboard']);
      } else {
        this.flashMessage.show(data.msg, {
          cssClass: 'alert-danger',
          timeout: 5000});
        this.router.navigate(['login']);
      }
    });
  }

Solution

  • I think you are talking about typescript error: http.post returns an Observable<object>, so data is an object, and there is no property token, user, msg in object.

    With the information you told us, your authenticate WS should return:

    interface SuccessResponse {
      token: string;
      user: any; // should change any to your user type
    }
    
    interface FailureResponse {
      success: false;
      msg: string;
    }
    
    type AuthResponse = SuccessResponse | FailureResponse;
    
    authenticateUser(user): Observable<AuthResponse> {
        // header for content-type is not needed
        return this.http.post<AuthResponse>('http://localhost:3000/users/authenticate', user);
    }
    

    You can use it like it:

     onLoginSubmit() {
        const user = {
          username: this.username,
          password: this.password
        }
    
        this.authService.authenticateUser(user).subscribe(response => {
          console.log(data);
          if ('token' in response) {
            // response is SuccessResponse
            this.authService.storeUserData(response.token, response.user);
            this.flashMessage.show('You are now logged in', {
              cssClass: 'alert-success',
              timeout: 5000});
            this.router.navigate(['dashboard']);
          } else {
            // response is FailureResponse
            this.flashMessage.show(response.msg, {
              cssClass: 'alert-danger',
              timeout: 5000});
            this.router.navigate(['login']);
          }
        });
      }
    

    That should work for you. However, the standard is that you should return an error (e.g code 401) when login failed, not an OK status (200) with success: false. The code will be different in this case