Issue
Folks:
I have an ionic app that has a page where user can post comments on a story. If a user posts new comment, the comment is displayed in the page. Comments are fetched from a REST API using the "let comment of postComments" fragment with *ngFor.
<ion-content *ngIf="!searchUser" #myContent padding [scrollEvents]="true">
<ion-refresher slot="fixed" (ionRefresh)="reloadPage($event)">
<ion-refresher-content pullingIcon="arrow-dropdown" refreshingSpinner="circles" refreshingText="Refreshing..." >
</ion-refresher-content>
</ion-refresher>
<div class="post-content">
<ion-item lines="none" no-padding>
<ion-avatar slot="start">
<img [src]=" (profileUrl == null) ? 'assets/img/emptyperson.jpg' : profileUrl">
</ion-avatar>
<p class="user-post-text">
<strong>{{
username
}}</strong><span>
{{ description }}
</span>
</p>
</ion-item>
<div class="border"></div>
<ion-item-sliding class="comments-container" *ngFor="let comment of postComments; let i = index; let c = count;" [id]="'slidingItem' + i">
<ion-item no-padding lines="none">
<ion-avatar slot="start">
<img [src]=" (comment.profileUrl == null) ? 'assets/img/emptyperson.jpg' : comment.profileUrl">
</ion-avatar>
<p>
<strong>{{
comment.username
}}</strong>
{{ comment.comment }}
</p>
<ion-button
slot="end"
fill="clear"
(click)="likeButton(comment.id, comment.currentUserLike)"
[disabled]="disableLikeButton"
>
<ion-icon
*ngIf="!comment.currentUserLike"
slot="icon-only"
name="heart-outline"
color="black"
></ion-icon>
<ion-icon
*ngIf="comment.currentUserLike"
slot="icon-only"
name="heart"
color="danger"
></ion-icon>
</ion-button>
<br/>
</ion-item>
<ion-item-options *ngIf="isPostMine && (comment.userId != userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
<ion-item-option color="primary" >
<button color="primary" (click)="reportOffensive(comment.id,i)"><ion-icon class="inside-icon" name="remove-circle"></ion-icon> </button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="isPostMine && (comment.userId == userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="!isPostMine && (comment.userId != userdetails.id)">
<ion-item-option color="primary" >
<button color="primary" (click)="reportOffensive(comment.id,i)"><ion-icon class="inside-icon" name="remove-circle"></ion-icon> </button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="!isPostMine && (comment.userId == userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
</ion-item-options>
<p class="all-comments">
<span class="grey-text"> {{ comment.createdAt | timeAgo }}</span>
<span *ngIf="comment.numLikes > 0" class="grey-text tab" (click)="userList(comment.id,'CommentLikes')">{{comment.numLikes}} likes</span>
</p>
</ion-item-sliding>
</div>
</ion-content>
<ion-footer>
<ion-item lines="none">
<ion-avatar slot="start">
<img src="{{ userProfileUrl }}" />
</ion-avatar>
<ion-textarea autocapitalize="sentences" maxLength="255" type="text"
[(ngModel)]="commentContent" (ionChange)="getUsers($event)"
rows="1"
placeholder="Add a comment"
></ion-textarea>
<ion-icon class="blueicon" slot="end" name="send" (click)="addComment()"></ion-icon>
</ion-item>
</ion-footer>
In my typescript, I have a function addComment() which refreshes the value of postComments so that the page automatically reloads.
addComment() {
if (this.commentContent.trim()) {
this.showLoader("Posting Comment ...");
this.userPostComment.comment = this.commentContent;
this.userPostCommentJSON = JSON.stringify(this.userPostComment);
//console.log("Comment JSON is "+this.userPostCommentJSON);
this.https.post(this.serviceUrl+'comments',this.userPostCommentJSON,this.httpOptions)
.subscribe(
(res: any)=>{
this.commentContent = "";
this.refresh();
setTimeout(() => {
console.log("In Timeout");
this.refreshPostComments("");
this.events.publish('postComment:created', {
id: res.id,
time: new Date()
});
this.hideLoader();
this.commentContent = "";
},2000)
},
err => {
this.hideLoader();
this.showAlert(err);
}
);
}
}
This is working like charm, when I get to the Comments page from the story.
Here is my problem. If I navigate to the Comments page from a oneSignal push notification, everything works fine up to the point where I enter a new comment. When I enter a new Comment, the comment is created in the database using the RESTAPI (works fine), the refreshPostComments method is called in typescript (works fine), but my view does not get updated till I physically click the comment box again.
I don't know what I am doing wrong. But in my app.component.ts, I check for oneSignal notification clicked and if clicked, I do this
if (localStorage.getItem('auth-user') != undefined || null) {
if (additionalData.type == "comment") {
await console.log("Going to Comments");
this.router1.navigateForward(['/comments', {
userId: parseInt(additionalData.userId),
username: additionalData.username,
userPostId: parseInt(additionalData.userPostId),
description: additionalData.description,
profileNameKey: additionalData.profileNameKey
}]);
}
That works. Takes me to the Comments Page. But once I am in the page, I can do virtually everything else like peach, except if I add a comment, then it does not reflect in real time.
Any pointers on what I am missing?
JR
Solution
Found my solution. I think Angular’s Change detection is triggered by certain events, and when I was navigating to the page from OneSignal's notification - whatever OneSignal was using, it was not getting on Angular's radar. So I had to import ChangeDetectorRef and do a manual detectChanges() to make sure ngFor would detect the changes as soon as they occur.
Phew. Spent almost a half a day on this. So much for OneSignal and Angular's quirks with OneSignal. And Ionic had nothing to do with it.
Regards, JR
Answered By - John
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.