I have a chat page in my app where the chat-div is inside a wrapper-div. The structure looks like this:
<ion-content>
<div class="wrapper>
<div class="chatwindow">
<ion-grid>
<ion-row *ngFor="let message of messages">
<ion-col *ngIf="message.fromId !== myUid>
<div class="message other-message>
<span>{{message.text}}</span>
</div>
</ion-col>
<ion-col *ngIf="message.fromId === myUid>
<div class="message my-message>
<span>{{message.text}}</span>
</div>
</ion-col>
</ion-row>
</ion-grid>
</div>
</div
</ion-content>
My problem is that I am not able to make the chatpage scroll to bottom (both at pageload and when new messages arrives).
What I have tried so far:
TS: file
import {IonContent} from '#ionic/angular';
#ViewChild(‘content’) content: IonContent;
ngOninit(){
setTimeout(()=>{this.content.scrollToBottom();},200);
}
HTML file:
<ion-content #content>
Above does not give any effect, i also tried using ngZone and [scrollEvents=“true”].
The only thing that has given some effect is [ScrollTop]=“content.scrollheight”. But then the whole chatpage reloades everytime a message arrives and it scroll up and down very fast.
Any help with this will be much appreciated.
Thank you in advance.
Related
I have a list of image they come from an json array with 7 elements :
The key of image is
<ion-grid>
<ion-row *ngFor="let image of imageList; let i = index;">
<ion-col>
<div >
<img [src]="image.imageUrl" />
</div> </ion-col>
<ion-col>
<div >
<img [src]="image.imageUrl" />
</div>
</ion-col>
</ion-row>
</ion-grid>
But this code show me the same pic per row , I have tried to set image[i] on the first col and image[i+1] on the second but nothing.
I want to show two image per row like this but without same image.
Thanks.
Something like this should work:
<ion-grid>
<ion-row *ngFor="let image of imageList; let i = index;">
<ion-col>
<div >
<img [src]="imageList[i]?.imageUrl" />
</div> </ion-col>
<ion-col>
<div >
<img [src]="imageList[i + 1]?.imageUrl" />
</div>
</ion-col>
</ion-row>
Inside de *ngFor loop, the image will always be one image for every iteration. You should iterate the imageList and use the index to access the images from imageList. Hope it makes sense
So im using ionic with the firebase data and i have to load a lot of it.
And because of this massive data to load, not all images appear (As you can see on the screen shot).
So... what should i do and is it possible to lazy load the cards with the data.
there is my code
<div *ngIf="postcall1">
<ion-card (swipeleft)="goTochat(postscall1)" *ngFor="let postscall1 of postcall1">
<img class="pP" src="https://ucarecdn.com/{{ postscall1.profilePic }}/-/scale_crop/200x200/center/" />
<ion-img (press)="openOptionSheet(postcall1)" (click)="open(postscall1)"
src="https://ucarecdn.com/{{postscall1.postboost1ID}}/-/preview/{{postscall1.effect}}"></ion-img>
<ion-button mode="ios" class="this-button" color="light" fill="clear">
<ion-icon slot="icon-only" [name]="heartType"></ion-icon>
</ion-button>
</ion-card>
</div>
and i have these 3 firebase function to load
ngOnInit() {
const postcall = this.aff.httpsCallable('postscall')
this.sub = postcall({}).subscribe(data => {
this.postcall = data
console.log("postcall");
console.log(this.postcall);
})
///
const postcall1 = this.aff.httpsCallable('postscall1')
this.sub = postcall1({}).subscribe(data => {
this.postcall1 = data
console.log("postcall1");
console.log(this.postcall1);
})
}
thank you in advance
As you are using Ionic, put your items in an Ion virtual scroll.
In the documentation, it is clearly explained that only the necessary elements will be loaded.
For performance reasons, not every record in the list is rendered at once; instead a small subset of records (enough to fill the viewport) are rendered and reused as the user scrolls.
Not tested code below, but this example might help you.
<ion-virtual-scroll [items]="postcall1">
<ion-card *virtualItem="let postscall1">
<img class="pP" src="https://ucarecdn.com/{{ postscall1.profilePic }}/-/scale_crop/200x200/center/" />
<ion-img (press)="openOptionSheet(postcall1)" (click)="open(postscall1)"
src="https://ucarecdn.com/{{postscall1.postboost1ID}}/-/preview/{{postscall1.effect}}"></ion-img>
<ion-button mode="ios" class="this-button" color="light" fill="clear">
<ion-icon slot="icon-only" [name]="heartType"></ion-icon>
</ion-button>
</ion-card>
</ion-virtual-scroll>
Is there a way I can remove the entire image element from DOM when 403 error occurs to that image while fetching it from the API so that the title of the card is expanded to the whole width of the card.
This is what I tried so far
HTML
<div *ngFor="let item of items">
<ion-row>
<ion-col>
<div>{{ item.title }}</div>
</ion-col>
<ion-col size="4" class="ion-text-center">
<img src="{{ item.imageurl }}" (error)="handleImageError($event)" />
</ion-col>
</ion-row>
</div>
TS
handleImageError(e) {
e.target.style.display = 'none';
}
I have created a working example using StackBlitz. Could anyone please help.
You are looking for *ngIf on image container, as it removes / adds the element from the DOM. And you will also have to slightly modify the handleImageError.
StackBlitz
<div *ngFor="let item of items">
<ion-row>
<ion-col>
<div>{{ item.title }}</div>
</ion-col>
<ion-col *ngIf="!item.hide" size="4" class="ion-text-center">
<img [src]="item.imageurl" (error)="handleImageError(item)" />
</ion-col>
</ion-row>
</div>
And then in the script, in the handleImageError - do this:
items = [
{imageUrl: '5353ssa.png'},
{imageUrl: 'https://latam.kaspersky.com/content/es-mx/images/product-icon-KSOS.png'},
{imageUrl: '5353ssa.png'},
{imageUrl: '5353ssa.png'},
]
handleImageError(image) {
image.hide = true;
}
Your problem is about your container. U have two columns. Then u will hide column instead of image. U can use ngIf
https://stackblitz.com/edit/ionic-a5wy8u
<ion-col *ngIf="!car.isSHOW">
<ion-card-content>
<img src="{{car.url}}" (error)="handleImageError(car)">
</ion-card-content>
</ion-col>
in component change its to true
handleImageError(e) {
e.isSHOW = true;
}
I would suggest you to use ngIf to hide the complete image, the way I would have address this is
Create a boolean variable at the top of your component.
let shouldHide = false;
Use this variable and ngIf at your image, you can use this at the container level or the image level itself like.
<img src="{{ imageurl }}" (error)="handleImageError($event)" *ngIf="shoudHide"/>
Assign true in case of error
handleImageError(e) {
e.target.style.display = 'none';
this.shouldHide = true;
}
Hope it helps
I have a popover with ion-content. That content is replicated over a *ngFor with a maximum height of the ion-content to 400px. When the new content is added (from a user search) the scroll doesn't work properly on iOS. See below:
Chrome and Safari on my computer (working correctly):
On iOS, it is not setting the scroll area properly, same code. What you will see is I try to scroll to see the bottom of the list, but it bounces back up each time as if I were at the bottom of my content:
I tried putting it in an ion-list as well, I don't really want to do that though. It didn't work either.
Here is the HTML (scrollable is verified true, get-user-location class just sets max height to 400px):
<ion-content [scrollY]="scrollable" class="get-user-location">
<form [formGroup]="form">
<h5 padding no-margin *ngIf="message">{{ message }}</h5>
<ion-item>
<ion-input
color="primary"
(keyup.enter)="searchClicked()"
formControlName="search"
></ion-input>
<ion-button (click)="searchClicked()" fill="clear"
><ion-icon onclick="searchClicked()" name="search" slot="icon-only"></ion-icon
></ion-button>
</ion-item>
<ion-item *ngIf="searchStatus">
{{ searchStatus }}
</ion-item>
<ion-radio-group formControlName="radio" (ionSelect)="radioSelected($event)">
<ion-item *ngFor="let searchResult of searchResults; let i = index">
<ion-radio mode="md" value="{{ i }}" margin-end></ion-radio>
<ion-label>{{ searchResult!.name }}</ion-label>
</ion-item>
<ion-item>
<ion-radio mode="md" value="city" margin-end></ion-radio>
<ion-label>Default city listed below</ion-label>
</ion-item>
</ion-radio-group>
<ion-item>
<ion-select
okText="Okay"
cancelText="Dismiss"
formControlName="city"
(ionChange)="cityChanged($event)"
>
<ion-select-option *ngFor="let city of cities" [value]="city.id">
{{ city.name }}
</ion-select-option>
</ion-select>
</ion-item>
<ion-button
*ngIf="showSubmit"
(click)="dismiss()"
[disabled]="!form.valid"
fill="clear"
class="button-padding-start large"
margin
>Submit</ion-button
>
</form>
</ion-content>
It's a bug:
https://github.com/ionic-team/ionic/issues/16910
Remove ion-content and add this to your component's scss:
.backdrop-no-scroll ion-content {
--overflow: hidden;
}
Try
<ion-content no-bounce has-bouncing="false">
...
</ion-content>
I found out that if it's a ionic bug on iOS, there are multiple ways to "resolve" the issue.
(recommended) First:
Add a couple of empty ion-item at the end of the list with the property lines="none" (<ion-item lines="none"></ion-item>)
(I do not recommend) Second:
Set no-bounce has-bouncing="false" to the ion-content
(I do not recommend) Third:
Remove ion content and add to the CSS file .backdrop-no-scroll ion-content { --overflow: hidden; }
I've an ion-card that get its contents from a web server, all is working fine except linking ion-card click event to external url, below is my code
<ion-content no-padding >
<ion-item no-padding *ngFor="let item of items" >
<ion-card (click)="goToDetails('{{item.link}}')">
<img class="images" src="http://mydomain/{{item.captionImage}}">
<ion-item text-wrap>
<div class="headings">{{item.title}}</div>
</ion-item>
<ion-card-content text-wrap>
<p>{{item.message}}"</p>
</ion-card-content>
<ion-row>
<ion-col col-9>
<ion-row>
<ion-col>
<img class="owner-logo" src="http://mydomain/{{item.sourceLogo}}">
</ion-col>
<ion-col>
<div class="owner-name">{{item.source}}</div>
</ion-col>
<ion-col></ion-col>
<ion-col></ion-col>
<ion-col></ion-col>
</ion-row>
</ion-col>
<ion-col col-3 text-right>
<button ion-button clear small color="danger" icon-start (click)="regularShare(index)">
<ion-icon name='share'></ion-icon>
Share
</button>
</ion-col>
</ion-row>
</ion-card>
</ion-item>
</ion-content>
my .ts file is
public goToDetails(url : string){
let target = "_self";
this.theInAppBrowser.create(url,target,this.options);
}
I got this error message
Uncaught Error: Template parse errors:
Parser Error: Got interpolation ({{}}) where expression was expected at column 13.
You need to write ion-card like this
<ion-card (click)="goToDetails(item.link)">
If you are in in-build directive like click, ngIf you don't need to use interpolation