Home > other >  Typescript: handle data from service
Typescript: handle data from service

Time:05-06

I would like to display users' data, but I have a problem with displaying the correct profile pictures. If a user does not have a profile picture, I get "undefined" in the console. If one user has a profile picture, then the same picture will be displayed for all the users. I need help finding the error in my code.

export interface UserData {
 id: number,
 name: string
}

export interface UserWithImage extends UserData{
  image?: string
}

export interface UserProfileImage {
  id: number,
  url: string
}

After I get the necessary data from the services, I try to push the profile image into the userData.

user-data.ts

userData: UserWithImage[];
userProfiles: UserProfileImage[];
userProfileImage: UserProfileImage[];

getUserData() {
  this.userData = this.userService.getData();
  this.userProfiles = await this.imagesService.getProfilePicture(this.userData?.map(u => u.id));
  this.userProfileImage = this.userProfiles.filter(u => u.url);
  this.userData?.forEach((data, i) => {
    data.image = this.userProfileImage[i].url;
  });
}

images.service.ts

public async getProfilePicture(ids: number[]): Promise<UserProfileImage[]> {
  const toLoad = ids.filter(id => !this.userProfileImages.find(up => up.id === id)).map(u => u);
  if (toLoad || toLoad.length) {
  const loaded = (await firstValueFrom(this.httpClient.post<UserProfile[]> 
  (this.imgService.getServiceUrl(customersScope, `${basePath}settings/users/profil`), JSON.stringify(toLoad), {headers}))).map(sp => {
    return {
      id: sp.userId,
      url: sp.profilepicId ? this.imgService.getServiceUrl(customersScope, 
      `${basePath}web/download/profilepic/${sp.profilepicId}/users/${sp.userId}`, true) : ''
    } as UserProfileImage
  });
  this.userProfileImages = [...loaded, ...this.userProfileImages];
}
return this.userProfileImages;
}

user-data.html

<div ngFor="data of userData">
  <etc-profil [name]="data.name" [image]="data.image"></etc-profil>
</div>

CodePudding user response:

this.userData = this.userService.getData();

Is this an async function (i.e. are you missing an await)?

this.userProfiles = await this.imagesService.getProfilePicture(this.userData?.map(u => u.id));

This line would fail is this.userData is a promise. this.userProfiles would be undefined due to the use of optional chaining (?.)

this.userProfileImage = this.userProfiles.filter(u => u.url);

This line appears to do nothing, the filter predicate is saying that anything with a url property that is not null or undefined is included, but the interface says that url is non-optional and doesn't support null or undefined.

this.userData?.forEach((data, i) => {
  data.image = this.userProfileImage[i].url;
});

Again, if this.userData is a promise, this will do nothing due to the optional chaining.

If it does run, its assumed that there is a one-to-one relationship between users and profile images (index count and order must be the same).

I didn't consider the implementation of getProfilePicture because I think these issues need resolving first.

  • Related