2

I'm creating a login application from scratch. Everything works fine except one situation where I try to login then logout out and after I try to login again I get this error:

LoginFormComponent.html:23 ERROR TypeError: this.authService.authenticateUser is not a function
    at LoginFormComponent.onLoginSubmit (login-form.component.ts:50)
    at Object.eval [as handleEvent] (LoginFormComponent.html:23)
    at handleEvent (core.js:13547)
    at callWithDebugContext (core.js:15056)
    at Object.debugHandleEvent [as handleEvent] (core.js:14643)
    at dispatchEvent (core.js:9962)
    at eval (core.js:10587)
    at HTMLButtonElement.eval (platform-browser.js:2628)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4740) 

Here is the code from 2 files. First is Auth.service. A user service that is injected in login-form.component.js which is the second file where I communicate with backend server.

auth.service.js

import { Injectable } from '@angular/core';
import { Http, Headers} from '@angular/http';
import 'rxjs/add/operator/map';
import {tokenNotExpired} from 'angular2-jwt';
@Injectable()
export class AuthService {
  authToken: any;
  user: any;

  constructor(private http: Http) {}
  registerUser(user) {
    const headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return this.http.post('http://localhost:3000/users/register', user, {headers: headers})
    .map(res => res.json());
  }
  authenticateUser(user) {
    const headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return this.http.post('http://localhost:3000/users/authenticate', user, {headers: headers})
    .map(res => res.json());
  }
  getProfile() {
      const headers = new Headers();
      this.loadToken();
      headers.append('Authorization', this.authToken);
      headers.append('Content-Type', 'application/json');
      return this.http.get('http://localhost:3000/users/profile', {headers: headers})
      .map(res => res.json());
  }
  storeUserData(token, user) {
    localStorage.setItem('id_token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authenticateUser = token;
    this.user = user;
  }

  loadToken() {
    const token = localStorage.getItem('id_token');
    this.authToken = token;
  }
  logout() {
    this.authenticateUser = null;
    this.user  = null;
    localStorage.clear();
  }
  loggedIn() {
    return tokenNotExpired('id_token');
  }
}

login-form.component.js

import {Component, OnInit, EventEmitter, Output} from '@angular/core';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelectModule} from '@angular/material/';
import {MatIconModule} from '@angular/material/';
import {Router} from '@angular/router';
import { FormControl, Validators, FormGroup, FormBuilder, FormGroupDirective, NgForm} from '@angular/forms';
import {AuthService} from '../../services/auth.service';
import {MatSnackBar, MatSnackBarConfig} from '@angular/material';
@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.scss']
})
export class LoginFormComponent implements OnInit {
  showError: boolean;
  error: String;
  loginForm: any;
  // authService: AuthService;
  constructor(
    private router: Router,
    private readonly formBuilder: FormBuilder,
    private snackBar: MatSnackBar,
    private authService: AuthService) {
    this.loginForm = formBuilder.group({
      username: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(8), Validators.maxLength(30)]]
    });
  }

  trigger = false;
  isLoginPassed = false;
  @Output() public LoginEvent = new EventEmitter();

  closeLoginForm() {
    this.trigger = false;
    this.LoginEvent.emit(this.trigger);
  }
  openSnackBar(msg: String, color: String) {
    // open Box that shows if the account has been been logged in
    this.snackBar.open( msg.toString() , 'Close', {
      duration: 3000,
      panelClass: [color.toString()]
    });
  }
  onLoginSubmit() {
    const user = {
      username: this.loginForm.controls['username'].value,
      password: this.loginForm.controls['password'].value
    };
    this.authService.authenticateUser(user).subscribe(data => {
      if (data.success) {
        this.authService.storeUserData(data.token, data.user);
        this.openSnackBar('You have been logged in', 'confirm');
        this.router.navigate(['main']);
        this.closeLoginForm();
      } else {
        this.loginForm.reset();
        this.openSnackBar(data.message, 'warning');
      }
    });
  }

  ngOnInit() {
  }

}

HTML where I'm calling the function onLoginSubmit()

<div class="wrapper" *ngIf="!isLoginPassed">
  <div class="logInWindow">
    <div class="title">
      <h1>Log In to BANDZ account </h1>
      <div class="x" (click)=closeLoginForm()></div>
    </div>
    <div class="Container">
      <form action="" method="post" [formGroup]="loginForm" class="form form-login">
        <mat-form-field>
          <mat-label>
            <mat-icon>email</mat-icon>
            Username
          </mat-label>
          <input type="text" matInput placeholder="Please provide your username" formControlName="username">
        </mat-form-field>
        <mat-form-field>
          <mat-label>
            <mat-icon>lock-outline</mat-icon>
            Password
          </mat-label>
          <input type="password" matInput placeholder="Please provide your password" formControlName="password">
        </mat-form-field>
        <button [disabled]="!loginForm.valid" (click)="onLoginSubmit()" mat-raised-button>Log in</button>
        <a id="lostPassword" href="#">Lost your password?</a>
        <br>
        <a id="registerAccount" href="#">Don't have an account?</a>

      </form>
    </div>
  </div>
</div>

I think something is wrong with "binding" but don't know where to start. If you have any tips how to handle this problem I would appreciate this.

1
  • Hello Sajeetharan. I added html code where I'm calling the function. Commented Apr 5, 2018 at 3:07

1 Answer 1

4

It's because you are accidentally setting that function to null in your logout method.

logout() {
   this.authenticateUser = null;
    ...
}

Did you mean to set the authToken to null instead?

Sign up to request clarification or add additional context in comments.

4 Comments

Oh yes of course my mistake. Really stupid mistake. The sad part is that the error still remains ... LoginFormComponent.html:23 ERROR TypeError: this.authService.authenticateUser is not a function at LoginFormComponent.onLoginSubmit (login-form.component.ts:49)
It happens AFTER I login successfully > logout and try to log in again
You are making a similar mistake in your storeUserData method as well...
I'm ashamed of myself don't know what I was thinking when I was writing this. Thank you Daniel for spotting this. It of course fixed the problem. I was just setting the function to null therefore the error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.