on my angular app i have a error on browser debug:
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'fields')
Why I cannot access to fields property in this line?
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
this is my user model
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;
}
this is my data
{
"_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"
}
}
my component
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();
}
}
CodePudding user response:
the field fields
is read on undefined
meaning your currentUser
is undefined, indeed, you are never setting the value of currentUser
before the constructor, I guess your code should be
this.authenticationService.currentUser.subscribe(x => {
this.currentUser = x
this.pictureUrl = this.currentUser.version.fields.field[0].fieldValue.path;
});
and you should check after if the picture url is set
CodePudding user response:
this.currentUser.version
is undefined
, caused by an extremely common mistake in asynchronous programming.
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
depends on the assignment from the observable immediately before it, but since that is an asynchronous function, it does not wait for it to complete before continuing to assign this.pictureUrl
.
You need to assign it within the observable, commonly I do this in the oncomplete
handler, though it can be on the onnext
handler as well. oncomplete
is only invoked if there was no error.
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
);
}
You should also consider doing this in the Angular lifecycle hook ngOnInit()
and not the constructor.
CodePudding user response:
this is AuthenticationService
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { Router } from '@angular/router';
import { EzUser } from '../_models/ezuser';
import { EzSession } from '../_models/ezsession';
import { User } from '../_models';
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private currentUserSubject: BehaviorSubject<EzUser>;
public currentUser: Observable<EzUser>;
private currentSessionSubject: BehaviorSubject<EzSession>;
public currentSession: Observable<EzSession>;
constructor(private http: HttpClient, private router: Router) {
this.currentUserSubject = new BehaviorSubject<EzUser>(JSON.parse(sessionStorage.getItem('ezuser')));
this.currentUser = this.currentUserSubject.asObservable();
this.currentSessionSubject = new BehaviorSubject<EzSession>(JSON.parse(sessionStorage.getItem('ezsession')));
this.currentSession = this.currentSessionSubject.asObservable();
}
public get currentSessionValue(): EzSession {
return this.currentSessionSubject.value;
}
public get currentUserValue(): any {
return this.currentUserSubject.value;
}
login(username: string, pass: string): Observable<EzUser> {
const headers = {
headers: new HttpHeaders({
Accept: 'application/vnd.ez.api.Session json',
'Content-Type': 'application/vnd.ez.api.SessionInput json',
})
};
const body = {
SessionInput: {
login: username,
password: pass
}
};
return this.http.post<EzSession>(`${environment.apiUrl}/user/sessions`, body, headers).pipe(
map(result => {
// store user details and basic auth credentials in local storage to keep user logged in between page refreshes
// session.authdata = window.btoa(username ':' pass);
// sessionStorage.setItem('currentUser', JSON.stringify(session));
result.authdata = window.btoa(username ':' pass);
sessionStorage.setItem('ezsession', JSON.stringify(result));
this.currentSessionSubject.next(result);
return result;
}),
mergeMap((x) => {
const ezsession = JSON.parse(sessionStorage.getItem('ezsession'));
const headers2 = {
headers: new HttpHeaders({
'Content-Type': ezsession.Session['_media-type'],
Accept: ezsession.Session.User['_media-type']
})
};
return this.http.get<any>(`${ezsession.Session.User['_href']}`, headers2).pipe(map(result => {
debugger
sessionStorage.setItem('ezuser', JSON.stringify(result.User));
this.currentUserSubject.next(result);
return result.User;
}));
})
);
}
logout(): Observable<any[]> {
const ezsession = JSON.parse(sessionStorage.getItem('ezsession'));
const headers = {
headers: new HttpHeaders({
Cookie: ezsession.Session.name '=' ezsession.Session.identifier,
'X-CSRF-Token': ezsession.Session.csrfToken
})
};
return this.http.delete<any>(`${environment.apiUrl}/user/sessions/${ezsession.Session.identifier}`, headers).pipe(
map(result => {
sessionStorage.removeItem('ezsession');
sessionStorage.removeItem('ezuser');
this.currentSessionSubject.next(null);
this.currentUserSubject.next(null);
return result;
})
);
}
}