Angular:: 错误 TS2532:对象可能是 'undefined'
Angular:: error TS2532: Object is possibly 'undefined'
我在做 angular Tour-hero 项目(将 Hero 替换为 'User')。当我将 Hero(User) 和 Hero-detail(User-detail) 分开并尝试访问详细信息时,它没有显示,更新功能也不起作用。它显示此错误:
error TS2532: Object is possibly 'undefined'.
6 <input id="user-name" [(ngModel)]="user.name"
placeholder="name">
我认为 user
对象给出了问题。但是,当我尝试完全按照本教程添加 MessageService 和所有内容时,它起作用了。但是当我删除所有这些时,它给出了这个错误。
在此先感谢您的帮助。
用户-detail.component.html:
<div>
<h2>{{user.name | uppercase}} Details</h2>
<div><span>id: </span>{{user.id}}</div>
<div>
<label for="user-name">User name: </label>
<input id="user-name" [(ngModel)]="user.name" placeholder="name">
</div>
<button (click)="goBack()">Back</button>
<button (click)="save()">Save</button>
</div>
用户-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
user?: User
constructor(
private userService: UserService,
private location: Location,
private route: ActivatedRoute
) { }
ngOnInit(): void {
this.getUser();
}
getUser(): void {
const id =
parseInt(this.route.snapshot.paramMap.get('id')!, 1);
this.userService.getUser(id)
.subscribe(user => this.user = user);
}
goBack(): void {
this.location.back();
}
save():void {
if(this.user){
this.userService.updateUser(this.user)
.subscribe(() => this.goBack())
}
}
}
user.service.ts:
import { Injectable } from '@angular/core';
import { User } from 'src/app/model/user';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UserService {
private usersUrl = 'api/users/';
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json'})
};
getUsers(): Observable<User[]> {
return this.http.get<User[]>(this.usersUrl).pipe(
catchError(this.handleError<User[]>('getUsers',[]))
);
}
/** GET hero by id. Will 404 if id not found */
getUser(id: number): Observable<User> {
const url = `${this.usersUrl}/${id}`;
return this.http.get<User>(url).pipe(
catchError(this.handleError<User>(`getUser id=${id}`))
);
}
updateUser(user: User): Observable<any> {
return this.http.put(this.usersUrl, user, this.httpOptions)
.pipe(
catchError(this.handleError<User[]>('getUsers',[]))
);
}
addUser(user: User): Observable<User>{
return this.http.post<User>(this.usersUrl, user, this.httpOptions)
.pipe(
catchError(this.handleError<User>('addUser'))
)
}
deleteUser(id: number): Observable<User>{
const url = `${this.usersUrl}/${id}`;
return this.http.delete<User>(url, this.httpOptions).pipe(
catchError(this.handleError<User>('deleteUser'))
)
}
constructor(private http: HttpClient) { }
private handleError<T>(operation = 'operation', result?:T){
return (error: any): Observable<T> => {
console.error(error);
return of(result as T);
}
}
}
您不需要将用户标记为可选
用户-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
user: User
constructor(
private userService: UserService,
private location: Location,
private route: ActivatedRoute
) { }
ngOnInit(): void {
this.getUser();
}
getUser(): void {
const id =
parseInt(this.route.snapshot.paramMap.get('id')!, 1);
this.userService.getUser(id)
.subscribe(user => this.user = user);
}
goBack(): void {
this.location.back();
}
save():void {
if(this.user){
this.userService.updateUser(this.user)
.subscribe(() => this.goBack())
}
}
}
我认为此错误是由于 typescript 2.1 版或更高版本引起的,您的代码非常完美!没有任何问题,但变量未初始化的减速方式可能会导致此错误,
现在,如果您知道用户值或者您想使用任何默认值进行初始化,那么请在构造函数中初始化您的用户变量,如下所示
user: User;
constructor() {
this.user = {
id: 0,
name: ''
};
}
另一个解决方案是利用 'Definite Assignment Assertion' 告诉打字稿这个变量将在运行时有一个值,如下所示
component.ts
user!: User;
同时使用 component.html 文件进行更改,如下所示
<div>
<h2>{{user?.name! | uppercase}} Details</h2>
<div><span>id: </span>{{user?.id!}}</div>
<div>
<label for="user-name">User name: </label>
<input id="user-name" [(ngModel)]="user?.name!" placeholder="name">
</div>
<button (click)="goBack()">Back</button>
<button (click)="save()">Save</button>
</div>
我在做 angular Tour-hero 项目(将 Hero 替换为 'User')。当我将 Hero(User) 和 Hero-detail(User-detail) 分开并尝试访问详细信息时,它没有显示,更新功能也不起作用。它显示此错误:
error TS2532: Object is possibly 'undefined'.
6 <input id="user-name" [(ngModel)]="user.name" placeholder="name">
我认为 user
对象给出了问题。但是,当我尝试完全按照本教程添加 MessageService 和所有内容时,它起作用了。但是当我删除所有这些时,它给出了这个错误。
在此先感谢您的帮助。
用户-detail.component.html:
<div>
<h2>{{user.name | uppercase}} Details</h2>
<div><span>id: </span>{{user.id}}</div>
<div>
<label for="user-name">User name: </label>
<input id="user-name" [(ngModel)]="user.name" placeholder="name">
</div>
<button (click)="goBack()">Back</button>
<button (click)="save()">Save</button>
</div>
用户-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
user?: User
constructor(
private userService: UserService,
private location: Location,
private route: ActivatedRoute
) { }
ngOnInit(): void {
this.getUser();
}
getUser(): void {
const id =
parseInt(this.route.snapshot.paramMap.get('id')!, 1);
this.userService.getUser(id)
.subscribe(user => this.user = user);
}
goBack(): void {
this.location.back();
}
save():void {
if(this.user){
this.userService.updateUser(this.user)
.subscribe(() => this.goBack())
}
}
}
user.service.ts:
import { Injectable } from '@angular/core';
import { User } from 'src/app/model/user';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UserService {
private usersUrl = 'api/users/';
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json'})
};
getUsers(): Observable<User[]> {
return this.http.get<User[]>(this.usersUrl).pipe(
catchError(this.handleError<User[]>('getUsers',[]))
);
}
/** GET hero by id. Will 404 if id not found */
getUser(id: number): Observable<User> {
const url = `${this.usersUrl}/${id}`;
return this.http.get<User>(url).pipe(
catchError(this.handleError<User>(`getUser id=${id}`))
);
}
updateUser(user: User): Observable<any> {
return this.http.put(this.usersUrl, user, this.httpOptions)
.pipe(
catchError(this.handleError<User[]>('getUsers',[]))
);
}
addUser(user: User): Observable<User>{
return this.http.post<User>(this.usersUrl, user, this.httpOptions)
.pipe(
catchError(this.handleError<User>('addUser'))
)
}
deleteUser(id: number): Observable<User>{
const url = `${this.usersUrl}/${id}`;
return this.http.delete<User>(url, this.httpOptions).pipe(
catchError(this.handleError<User>('deleteUser'))
)
}
constructor(private http: HttpClient) { }
private handleError<T>(operation = 'operation', result?:T){
return (error: any): Observable<T> => {
console.error(error);
return of(result as T);
}
}
}
您不需要将用户标记为可选
用户-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
user: User
constructor(
private userService: UserService,
private location: Location,
private route: ActivatedRoute
) { }
ngOnInit(): void {
this.getUser();
}
getUser(): void {
const id =
parseInt(this.route.snapshot.paramMap.get('id')!, 1);
this.userService.getUser(id)
.subscribe(user => this.user = user);
}
goBack(): void {
this.location.back();
}
save():void {
if(this.user){
this.userService.updateUser(this.user)
.subscribe(() => this.goBack())
}
}
}
我认为此错误是由于 typescript 2.1 版或更高版本引起的,您的代码非常完美!没有任何问题,但变量未初始化的减速方式可能会导致此错误,
现在,如果您知道用户值或者您想使用任何默认值进行初始化,那么请在构造函数中初始化您的用户变量,如下所示
user: User;
constructor() {
this.user = {
id: 0,
name: ''
};
}
另一个解决方案是利用 'Definite Assignment Assertion' 告诉打字稿这个变量将在运行时有一个值,如下所示
component.ts
user!: User;
同时使用 component.html 文件进行更改,如下所示
<div>
<h2>{{user?.name! | uppercase}} Details</h2>
<div><span>id: </span>{{user?.id!}}</div>
<div>
<label for="user-name">User name: </label>
<input id="user-name" [(ngModel)]="user?.name!" placeholder="name">
</div>
<button (click)="goBack()">Back</button>
<button (click)="save()">Save</button>
</div>