ERROR:TypeError:无法读取未定义的属性“用户名”

时间:2019-07-09 06:09:55

标签: angular

TypeError: Cannot read property 'username' of undefined
    at Object.eval [as updateDirectives] (AppComponent.html:6)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:36055)
    at checkAndUpdateView (core.js:35067)
    at callViewAction (core.js:35433)
    at execEmbeddedViewsAction (core.js:35390)
    at checkAndUpdateView (core.js:35068)
    at callViewAction (core.js:35433)
    at execComponentViewsAction (core.js:35361)
    at checkAndUpdateView (core.js:35074)
    at callWithDebugContext (core.js:36407)

我的代码运行正常。.偶然我删除了用户,但是重新创建了配置文件。.因为那样,在尝试与用户登录时出现了以上错误。.附加了component.ts..Can我需要帮助吗?

app.component.ts

import {Component, OnInit} from '@angular/core';
import {UserService} from './user.service';
import {throwError} from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  public users: any;
  /**
   * An object representing the user for the login form
   */
  public user: any;

  constructor(public _userService: UserService) { }

  ngOnInit() {
    this.user = {
      username: '',
      password: ''
    };
  }

  login() {
    this._userService.login({'username': this.user.username, 'password': this.user.password});
  }

  refreshToken() {
    this._userService.refreshToken();
  }

  logout() {
    this._userService.logout();
  }

  getUsers() {
    this.users = this._userService.getUsers();
   }
}

这是模板。.虽然我还没有更改此文件中的任何内容。 app.component.html

<h2>Log In</h2>
<div class="row" *ngIf="!_userService.token">
  <div class="col-sm-4">
    <label>Username:</label><br />
    <input type="text" name="login-username" [(ngModel)]="user.username">
    <span *ngFor="let error of _userService.errors.username"><br/>{{ error }}</span></div>
  <div class="col-sm-4">
    <label>Password:</label><br />
    <input type="password" name="login-password" [(ngModel)]="user.password">
    <span *ngFor="let error of _userService.errors.password"><br/>{{ error }}</span>
  </div>
  <div class="col-sm-4">
    <button (click)="login()" class="btn btn-primary">Log In</button>&nbsp;
  </div>
  <div class="col-sm-12">
    <span *ngFor="let error of _userService.errors.non_field_errors">{{ error }}<br /></span>
  </div>
</div>
<div class="row" *ngIf="_userService.token">
  <div class="col-sm-12">You are logged in as {{ _userService.username }}.<br />
    Token Expires: {{ _userService.token_expires }}<br />
    <button (click)="refreshToken()" class="btn btn-primary">Refresh Token</button>&nbsp;
    <button (click)="getUsers()" class="btn btn-primary">Get Users</button>
    <button (click)="logout()" class="btn btn-primary">Log Out</button>&nbsp;
  </div>
</div>

user.service.ts

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';


@Injectable()
export class UserService {

  // http options used for making API calls
  private httpOptions: any;

  // the actual JWT token
  public token: string;

  // the token expiration date
  public token_expires: Date;

  // the username of the logged in user
  public username: string;

  // user array
  public userList: any = [];

  // error messages received from the login attempt
  public errors: any = [];

  constructor(private http: HttpClient) {
    this.httpOptions = {
      headers: new HttpHeaders({'Content-Type': 'application/json'})
    };
  }

  // Uses http.post() to get an auth token from djangorestframework-jwt endpoint
  public login(user) {
    this.http.post('/api-token-auth/', JSON.stringify(user), this.httpOptions).subscribe(
      data => {
        console.log('login success', data);
        this.updateData(data['token']);
        localStorage.setItem('token', data['token']);
      },
      err => {
        this.errors = err['error'];
      }
    );
  }

  /**
   * Refreshes the JWT token, to extend the time the user is logged in
   */
  public refreshToken() {
    this.http.post('/api-token-refresh/', JSON.stringify({token: this.token}), this.httpOptions).subscribe(
      data => {
        console.log('refresh success', data);
        this.updateData(data['token']);
        localStorage.setItem('token', data['token']);
      },
      err => {
        console.error('refresh error', err);
        this.errors = err['error'];
      }
    );
  }

  public getUsers() {
    this.http.get('/api-users/', {
      headers: new HttpHeaders({
        'Content-type': 'application/json',
        'Authorization': localStorage.getItem('token')
      })
    }).subscribe(
      data => {
        this.userList = data['token'];
      },
      err => {
        console.error('authorization error', err);
        this.errors = err['error'];
      }
    );
  }

  public logout() {
    this.token = null;
    this.token_expires = null;
    this.username = null;
    localStorage.removeItem('token');
  }

  private updateData(token) {
    this.token = token;
    this.errors = [];

    // decode the token to read the username and expiration timestamp
    const token_parts = this.token.split(/\./);
    const token_decoded = JSON.parse(window.atob(token_parts[1]));
    this.token_expires = new Date(token_decoded.exp * 1000);
    this.username = token_decoded.username;
  }

}

2 个答案:

答案 0 :(得分:0)

对象用户变得不确定,您正在使用undefined.username。采用 {{user?.username}}

答案 1 :(得分:0)

您的user变量最初是未定义的。首先尝试将user设置为空对象。

public user: any = {};

您也可以使用@Syam的答案,但不需要添加插值。只需将html中的ngModel更改为[(ngModel)]="user?.username"

编辑:我刚刚注意到您代码中的下一行。在您的ngFor中,您拥有let error of _userService.errors.username。由于您已将其声明为_userService,因此您将无法在html中访问private。在组件的构造器中,将private _userService: UserService更改为public _userService: UserService,同时确保errors中存在UserService