I am doing a webproject where i need friendship/follow functionality. I also have two roles admins and (regular) users. Users can follow other users. Admins can not follow users.
A user can follow another user by clicking on a Follow ("Volgen)" button. If the user already follows an user an unfollow ("ontvolgen") will be shown. With the use of a custom pure pipe i check wether the user already follows a user.
A users sees either the follow or unfollow button. An admin is only able to see a delete button.
This is the code of the pipe:
@Pipe({
name: 'includes',
pure: true,
})
export class IncludesPipe<T> implements PipeTransform {
transform(array: T[], item: T): boolean {
return array.includes(item);
}
}
This is the use of the custom created 'includes' pipe in html:
<div
<table class="table tableborder table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Voornaam</th>
<th scope="col">Achternaam</th>
<th scope="col">Stad</th>
<th *ngIf="isUser || isAdmin" scope="col"></th>
</tr>
</thead>
<tbody *ngIf="users.length > 0">
<tr *ngFor="let user of filteredUsers; let i = index">
<th scope="row">{{ i + 1 }}</th>
<td>{{ user.firstName | titlecase }}</td>
<td>{{ user.lastName | titlecase }}</td>
<td>{{ user.city | titlecase }}</td>
<div
*ngIf="
currentlyFollowing | includes : user._id;
then unfollowTemplate;
else followTemplate
"
></div>
<ng-template #followTemplate>
<td>
<a
(click)="followUser(user._id)"
class="btn customfriendbutton"
>Volgen</a
>
</td>
</ng-template>
<ng-template #unfollowTemplate>
<td>
<a
(click)="unfollowUser(user._id)"
class="btn customcancelbutton"
>Ontvolgen</a
>
</td>
</ng-template>
<td *ngIf="isAdmin">
<a
(click)="sweetAlertDeleteConfirmation(user._id)"
class="btn customdeletebutton"
>
Verwijderen
</a>
</td>
</tr>
</tbody>
<tbody *ngIf="users.length === 0">
<td colspan="5">
<h2 class="text-center">Er zijn geen leden gevonden!</h2>
</td>
</tbody>
</table>
I keep track of the role of the current logged in user with a boolean: "isUser". This works perfectly untill i add another expression in ngIf statement where the pipe is located like so:
<div
*ngIf="
isUser && currentlyFollowing | includes : user._id;
then unfollowTemplate;
else followTemplate
"
></div>
When im logged in with an admin account and thus isUser equals false, the data is not loaded correctly. first images shows correct data: Correct data Second images shows missing data: Incorrect data
as you can see some rows of data are missing and the delete button wont show in every row.
I do not understand why the data does not load correctly when isUser is added to the ngIf statement. I expect that neither of the ng templates are shown and the "verwijderen" (delete) button will be shown in every row. Somehow the isUser in ngIf breaks it.
This is the error i get in the console: error in console
Removing the boolean isUser from the ngIf statement fixed my problem. But i want to know why so i get a beter understanding.
How you expect this code to work:
(isUser) && (currentlyFollowing | includes : user._id)
How it actually works as per how you wrote it:
(isUser && currentlyFollowing) | includes : user._id
So your includes
pipe receives a boolean false
value when isUser is false:
true && [1,2,3] => [1,2,3]
false && [1,2,3] => false
To fix - add some (
and )
:
<div
*ngIf="
isUser && (currentlyFollowing | includes : user._id);
then unfollowTemplate;
else followTemplate
"
></div>
(note: reload build-in browser on sandbox manually, it acts a bit buggy)