Angular-订阅功能时无法读取未定义的属性
在我的 Angular 应用程序上,我在浏览器调试时遇到错误:
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'fields')
为什么我无法访问此行中的 fields 属性?
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
这是我的用户模型
export interface EzUser {
mediaType: string;
href: string;
id: number;
remoteID: string;
contentType: ContentType;
name: string;
versions: ContentType;
section: ContentType;
mainLocation: ContentType;
locations: ContentType;
groups: ContentType;
owner: ContentType;
publishDate: Date;
lastModificationDate: Date;
mainLanguageCode: string;
alwaysAvailable: boolean;
version: Version;
login: string;
email: string;
enabled: boolean;
userGroups: ContentType;
roles: ContentType;
}
export interface ContentType {
mediaType: string;
href: string;
}
export interface Version {
mediaType: string;
href: string;
versionInfo: VersionInfo;
fields: Fields;
relations: Relations;
thumbnail: Thumbnail;
}
export interface Fields {
field: Field[];
}
export interface Field {
id: number;
fieldDefinitionIdentifier: string;
languageCode: string;
fieldTypeIdentifier: string;
fieldValue: FieldValueClass;
}
export interface FieldValueClass {
hasStoredLogin?: boolean;
contentID?: number;
login?: string;
email?: string;
passwordUpdatedAt?: number;
enabled?: boolean;
maxLogin?: number;
plainPassword?: null;
id?: string;
path?: string;
alternativeText?: string;
fileName?: string;
fileSize?: number;
imageID?: string;
uri?: string;
inputURI?: null;
width?: string;
height?: string;
additionalData?: any[];
variations?: Variations;
}
export interface Variations {
ezplatformAdminUIProfilePictureUserMenu: string;
large: string;
medium: string;
reference: string;
small: string;
tiny: Href;
}
export interface Href {
href: string;
}
export interface Relations {
mediaType: string;
href: string;
relation: any[];
}
export interface Thumbnail {
mediaType: string;
resource: string;
width: null;
height: null;
mimeType: string;
}
export interface VersionInfo {
id: number;
versionNo: number;
status: string;
modificationDate: Date;
creator: ContentType;
creationDate: Date;
initialLanguageCode: string;
languageCodes: string;
versionTranslationInfo: VersionTranslationInfo;
names: Names;
content: ContentType;
}
export interface Names {
value: Value[];
}
export interface Value {
languageCode: string;
text: string;
}
export interface VersionTranslationInfo {
mediaType: string;
language: Language[];
}
export interface Language {
languageCode: string;
}
这是我的数据
{
"_media-type": "application/vnd.ez.api.User+json",
"_href": "/api/ezp/v2/user/users/14",
"_id": 14,
"_remoteId": "1bb4fe25487f05527efa8bfd394cecc7",
"ContentType": {
"_media-type": "application/vnd.ez.api.ContentType+json",
"_href": "/api/ezp/v2/content/types/4"
},
"name": "Administrator User",
"Versions": {
"_media-type": "application/vnd.ez.api.VersionList+json",
"_href": "/api/ezp/v2/content/objects/14/versions"
},
"Section": {
"_media-type": "application/vnd.ez.api.Section+json",
"_href": "/api/ezp/v2/content/sections/2"
},
"MainLocation": {
"_media-type": "application/vnd.ez.api.Location+json",
"_href": "/api/ezp/v2/content/locations/1/5/13/15"
},
"Locations": {
"_media-type": "application/vnd.ez.api.LocationList+json",
"_href": "/api/ezp/v2/content/objects/14/locations"
},
"Groups": {
"_media-type": "application/vnd.ez.api.UserGroupRefList+json",
"_href": "/api/ezp/v2/user/users/14/groups"
},
"Owner": {
"_media-type": "application/vnd.ez.api.User+json",
"_href": "/api/ezp/v2/user/users/14"
},
"publishDate": "2002-10-06T16:13:50+00:00",
"lastModificationDate": "2021-12-21T17:23:49+00:00",
"mainLanguageCode": "eng-GB",
"alwaysAvailable": true,
"Version": {
"_media-type": "application/vnd.ez.api.Version+json",
"_href": "/api/ezp/v2/content/objects/14/versions/5",
"VersionInfo": {
"id": 517,
"versionNo": 5,
"status": "PUBLISHED",
"modificationDate": "2021-12-21T17:23:49+00:00",
"Creator": {
"_media-type": "application/vnd.ez.api.User+json",
"_href": "/api/ezp/v2/user/users/14"
},
"creationDate": "2021-12-21T17:23:48+00:00",
"initialLanguageCode": "eng-GB",
"languageCodes": "eng-GB",
"VersionTranslationInfo": {
"_media-type": "application/vnd.ez.api.VersionTranslationInfo+json",
"Language": [{
"languageCode": "eng-GB"
}]
},
"names": {
"value": [{
"_languageCode": "eng-GB",
"#text": "Administrator User"
}]
},
"Content": {
"_media-type": "application/vnd.ez.api.ContentInfo+json",
"_href": "/api/ezp/v2/content/objects/14"
}
},
"Fields": {
"field": [{
"id": 28,
"fieldDefinitionIdentifier": "first_name",
"languageCode": "eng-GB",
"fieldTypeIdentifier": "ezstring",
"fieldValue": "Administrator"
}, {
"id": 29,
"fieldDefinitionIdentifier": "last_name",
"languageCode": "eng-GB",
"fieldTypeIdentifier": "ezstring",
"fieldValue": "User"
}, {
"id": 30,
"fieldDefinitionIdentifier": "user_account",
"languageCode": "eng-GB",
"fieldTypeIdentifier": "ezuser",
"fieldValue": {
"hasStoredLogin": true,
"contentId": 14,
"login": "admin",
"email": "[email protected]",
"passwordUpdatedAt": 1640107428,
"enabled": true,
"maxLogin": 10,
"plainPassword": null
}
}, {
"id": 178,
"fieldDefinitionIdentifier": "signature",
"languageCode": "eng-GB",
"fieldTypeIdentifier": "eztext",
"fieldValue": "Mega boss"
}, {
"id": 180,
"fieldDefinitionIdentifier": "image",
"languageCode": "eng-GB",
"fieldTypeIdentifier": "ezimage",
"fieldValue": {
"id": "0/8/1/0/180-5-eng-GB/avatar_19.jpg",
"path": "/0/8/1/0/180-5-eng-GB/avatar_19.jpg",
"alternativeText": "",
"fileName": "avatar_19.jpg",
"fileSize": 50787,
"imageId": "14-180-5",
"uri": "/var/site/storage/images/0/8/1/0/180-5-eng-GB/avatar_19.jpg",
"inputUri": null,
"width": "480",
"height": "580",
"additionalData": [],
"variations": {
"ezplatform_admin_ui_profile_picture_user_menu": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/ezplatform_admin_ui_profile_picture_user_menu"
},
"large": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/large"
},
"medium": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/medium"
},
"reference": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/reference"
},
"small": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/small"
},
"tiny": {
"href": "/api/ezp/v2/content/binary/images/14-180-5/variations/tiny"
}
}
}
}]
},
"Relations": {
"_media-type": "application/vnd.ez.api.RelationList+json",
"_href": "/api/ezp/v2/content/objects/14/versions/5/relations",
"Relation": []
},
"Thumbnail": {
"_media-type": "application/vnd.ez.api.Thumbnail+json",
"resource": "/bundles/ezplatformadminui/img/ez-icons.svg#user",
"width": null,
"height": null,
"mimeType": "image/svg+xml"
}
},
"login": "admin",
"email": "[email protected]",
"enabled": true,
"UserGroups": {
"_media-type": "application/vnd.ez.api.UserGroupList+json",
"_href": "/api/ezp/v2/user/users/14/groups"
},
"Roles": {
"_media-type": "application/vnd.ez.api.RoleAssignmentList+json",
"_href": "/api/ezp/v2/user/users/14/roles"
}
}
我的组件
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/_models';
import { EzUser } from 'src/app/_models/ezuser';
import { AuthenticationService } from 'src/app/_services';
import { UserblockService } from './userblock.service';
@Component({
selector: 'app-userblock',
templateUrl: './userblock.component.html',
styleUrls: ['./userblock.component.scss']
})
export class UserblockComponent implements OnInit {
currentUser: EzUser;
error = '';
pictureUrl: string;
user: User = {
id: 1,
nome: 'ippo',
cognome: 'adad',
tipo: {id: 1, name: 'dsad'}
};
constructor(public userblockService: UserblockService, private authenticationService: AuthenticationService) {
this.authenticationService.currentUser.subscribe(x => this.currentUser = x);
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
}
ngOnInit() {}
userBlockIsVisible(): boolean{
return this.userblockService.getVisibility();
}
}
您收到错误:
Cannot read properties of undefined (reading 'fields')
在语句中:
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
这意味着
this.currentUser.version
是
未定义
查看问题中共享的 json 数据,没有
version
属性,实际上它的
Version
(大写
V
),因此
this.currentUser.version
将是
未定义
。
根据问题中共享的 json 数据,语句应为:
this.pictureUrl = this.currentUser.Version.Fields.field[0].fieldValue.path;
同样在 json 数据中,
this.currentUser.Version.Fields.field[0].fieldValue
值是一个字符串而不是对象,这可能在尝试读取
fieldValue.path
时再次导致错误。
"fieldValue": "Administrator"
确保模型定义和 json 数据之间的属性名称和类型同步,应该可以解决问题。
字段
fields
读取为
undefined
,这意味着您的
currentUser
未定义,事实上,您从未在构造函数之前设置
currentUser
的值,我猜您的代码应该是
this.authenticationService.currentUser.subscribe(x => {
this.currentUser = x
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
});
并且您应该在之后检查图片网址是否设置
this.currentUser.version
为
undefined
,这是由异步编程中极为常见的错误引起的。
constructor(public userblockService: UserblockService, private authenticationService: AuthenticationService) {
this.authenticationService.currentUser.subscribe(x => this.currentUser = x);
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
}
this.pictureUrl
依赖于它之前立即进行的可观察对象的分配,但由于这是一个异步函数,因此它不会等待其完成后再继续分配
this.pictureUrl
。
您需要在可观察对象内进行分配,通常我在
oncomplete
处理程序
中执行此操作,但也可以在
onnext
处理程序中进行分配。
oncomplete
仅在没有错误的情况下调用。
constructor(public userblockService: UserblockService, private authenticationService: AuthenticationService) {
this.authenticationService.currentUser.subscribe(
user => this.currentUser = user,
error => console.error,
_ => this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path
);
}
您还应该考虑在 Angular 生命周期钩子
ngOnInit()
中执行此操作,而不是在构造函数中执行此操作。