export interface Review {
_id: string;
locationId: string;
rating: number;
review: string;
userId: user | string;
}
interface user {
_id: string;
profile_pic: string;
first_name: string;
last_name: string;
}
reviews: Review[];
<div *ngFor="let review of reviews">
<img [src]="review.userId.profile_pic">
</div>
Identifier 'profile_pic' is not defined. 'string | user' does not contain such a member
The Error above is visible in my IDE. But Works fine while I run it on browser.
If you really want to stick with your current schema, you could use a custom pipe to set the type of userID to user where you know myUser will not be a string. Something like:
import { Pipe, PipeTransform } from '@angular/core';
// You will also need to import your `user` interface
@Pipe({name: 'assignUserType'})
export class ExponentialStrengthPipe implements PipeTransform {
transform(myUser): User {
return myUser as User;
}
}
Then you can use this in your template:
{{review.userId | assignUserType}}
As you might expect, this will error if myUser does not satisfy your interface user.
tl;dr - I would use approach 3 at the bottom of my answer.
As per the comment by @abhishek-ekaanth, I wouldn't recommend this approach:
userId: user | string;
Aside from the error, this will very likely cause you issues at some point, because there are two different possible paths to the ID of the user, depending on whether userId is a string or not.
If there are situations where you might only have a userId but not a user assigned to a Review, you could take one of the following approaches:
Approach 1:
Separate userId and user into two separate properties and make user optional:
export interface Review {
_id: string;
locationId: string;
rating: number;
review: string;
userId: string;
user?: user;
}
If you wanted to avoid repeating userId where a user, is present you could make userId optional too and populate one or the other, but as per my first point, I think this will cause you headaches.
Then in your template you can do:
<div *ngFor="let review of reviews">
<img *ngIf="review.user" [src]="review.user.profile_pic">
</div>
Which will only display the pic if review.user is populated.
Approach 2:
Probably closer you your initial approach:
export interface Review {
_id: string;
locationId: string;
rating: number;
review: string;
user: user;
}
interface user {
_id: string;
profile_pic?: string;
first_name?: string;
last_name?: string;
}
So where you have only a user ID, user would just be:
{
_id: 'myUserID'
}
This avoids repeating the user ID in Review and has the benefit of a consistent path to the user ID, whether the other properties of user are populated or not.
The drawback is the awkwardness of making all the other properties of user optional.
You can then do:
<div *ngFor="let review of reviews">
<img *ngIf="review.user.profile_pic" [src]="review.user.profile_pic">
</div>
Approach 3:
...because good things come in threes - this is the one I would use.
export interface Review {
_id: string;
locationId: string;
rating: number;
review: string;
user: user;
}
interface user {
_id: string;
userProperties?: UserProperties;
}
interface UserProperties {
profile_pic: string;
first_name: string;
last_name: string;
}
And in your template:
<div *ngFor="let review of reviews">
<img *ngIf="review.user.userProperties" [src]="review.user.userProperties.profile_pic">
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With