I'm trying to get the values from my API but I can't show them in ion-list.
Screenshot of the error:
As you can see in the image I got the data from my API but I can show them in ion-list.
The HTML is this
<ion-list>
<ion-item *ngFor="let item of (results | async)">
<ion-label text-wrap>{{item.nombreProducto}}</ion-label>
<ion-button color="light"><img src="../../assets/icon/binoculars.png" alt="" (click)="presentarModal()" item-end></ion-button>
<ion-button color="light"><img src="../../assets/icon/cart.png" alt="" (click)="addCart()" item-end></ion-button>
</ion-item>
I've created a service that has a method called getAll
getAll(): Observable<any>{
return this.http.get(`${this.url}`).pipe(
map(results=>{
console.log('Data', results);
return results['Data'];
})
);
}
And in my home.page.ts the getAll method contains this
getAll(){
this.results = this.productService.getAll();
}
You're trying to access a key in the array which does not exist. Your results is the data you are looking for that you want to return. Update your method to the following:
getAll(): Observable<any>{
return this.http.get(`${this.url}`).pipe(
map(results=>{
console.log('Data', results);
return results;
})
);
With angular versions 4.x and higher the syntax for the async pipe and how to reference it's values in the ngFor may be incorrect, try:
<ion-list>
<ion-item *ngFor="let item of results | async as item">
<ion-label text-wrap>{{item.nombreProducto}}</ion-label>
<ion-button color="light"><img src="../../assets/icon/binoculars.png" alt="" (click)="presentarModal()" item-end></ion-button>
<ion-button color="light"><img src="../../assets/icon/cart.png" alt="" (click)="addCart()" item-end></ion-button>
</ion-item>
This syntax change between angular versions is better explained here:
"While in version 2 we had to fallback to subscribing to the Observable in the component class, Angular version 4 now gives us a possibility to handle such scenario by assigning the async result from the Observable to a template variable"
https://juristr.com/blog/2017/06/new-enhanced-ngIf-and-ngFor/#enumerate-ngfor-loops-using-as-and-async-pipes
results is an array of objects, you are returning results['Data'] in your rxjs map which does not exist. I assume your own console.log confused you into thinking the structure has a Data property.
Related
I am working on the Ionic Project and it that I have the contact page which is fetching the details from the API. I want to apply the hyperlink according to the details fetched like if it is a mobile number then tel is applied and for the email mailto is applied.
This is my contact.html:
<ion-content padding overflow-scroll="true">
<ion-grid align-items-center justify-content-center>
<ion-row align-items-center justify-content-center>
<ion-col class="mycol22" col-12 *ngFor="let contdetails of this.detailscontact">
<h3 class="myneh31">{{contdetails?.sub_head}}</h3>
<hr />
<p class="newmyp2">{{contdetails?.sub_content_first}}</p>
<a href="tel or mailto"><p class="newmyp2">{{contdetails?.sub_content_second}}</p>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
The problem is that, How to decide whether to apply tel or mailto depending on the value fetched. This is my output according to the details fetched from the API. Now, I want to apply hyperlink depending upon the details fetched from the API. For Email: mailto will apply and for Mobile Number: tel will be applied.
Any help is much appreciated.
First you have to check if data is email type or not. Use this function as a email validator.
emailValidator(email:string): boolean {
var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!EMAIL_REGEXP.test(email)) {
return false;
}
return true;
}
And in your html page
To make yourself easy you can return string from emailValidator function:
emailValidator(email:string): string {
var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!EMAIL_REGEXP.test(email)) {
return 'mailto';
}
return 'tel';
}
and in HTML you can use
*ngIf should come handy:
... // or any boolean as condition
... // or any other condition
I'm making a list of items and everytime that the user input some value it calls the listVendas function that searches immediately in the API, but this cause a bunch of requests, and some requests can finish before others, so my question is.
How can I abort a Promise so I can create a new one?
listVendas(event?: any) {
let codigovenda;
if (event) {
codigovenda = event.value;
}
if (typeof this.promise != 'undefined') {
// HOW DO I ABORT THE PREVIOUS PROMISE
}
this.promise = this.vendaProvider.getAll(codigovenda);
this.promise.then(data => {
this.vendas = data;
})
}
In Ionic you can use the rxjs switchMap operator and debounceTime operator to do this very easily.
example code
I've searched a lot, and you can't abort a promise, so my solution was to don't make the request everytime the user type something, instead of that I created a button to make the request
<form [formGroup]="searchForm" (ngSubmit)="listVendas()">
<ion-card class="search">
<ion-icon class="icon-search" name="search"></ion-icon>
<ion-input type="number" pattern="[0-9]*" value="" formControlName="codigovenda"></ion-input>
<ion-icon class="icon-camera" name="camera" (click)="scanBacode()"></ion-icon>
</ion-card>
<ion-row class="row-submit" justify-content-center>
<button ion-button full icon-start type="submit">
Buscar
</button>
</ion-row>
</form>
When data get from ant+ device, page cannot show that on time.
code of ts:
this.antplus.subscribeHR(ID, (response) => {
this.heartrate = response.heartRate;
}, (error)=>console.log("error:" + error));
code of HTML:
<ion-item>
<button ion-button (click)="stopSearch();">Stop</button>
{{heartrate}}
</ion-item>
The value of heartrate just will update when page change.
This problem I also get on ionic-Native/stepcounter
how do i order it to display this array in the dropdown??
my.html
<ion-item>
<img src="assets/img/travel/city.png" width="25" height="30" item-start>
<ion-label stacked>Pilih Kota</ion-label>
<ion-select [(ngModel)]="shuttledestination2" name="shuttledestination2" interface="action-sheet">
<ion-option *ngFor="let data of traveldest" value="{{ data.id }}"><b>{{ data.label }}</b></ion-option>
</ion-select>
</ion-item>
Your traveldest clearly is an object of objects and not an arry, you can see by the image where the second line you have {1{...}, 2{...}, 3{...}}.
That you need to do is convert this object to an array before assigning it to traveldest, you can easy do this by using Object.values(yourObject), so you can do this:
this.traveldest = Object.values(yourReceivedObject);
yourReceivedObject is the response from your HTTP call or anything that is returning your results.
Hope this helps.
<ion-header-bar>
Showing at {{distance.current_scroll_distance}}
</ion-header-bar>
<ion-list>
<ion-item collection-repeat='results in data.results'>
{{result.name}} / {{result.distance}}
</ion-item>
</ion-list>
I need to detect scroll on the ion list, and then determine which is the first visible ion-item, to update current_scroll_distance on headbar.
help will be appreciated.
I do not understand referred to "Which is the first visible ion-item"?
Remember that each ng-repeat there is a $ index! and that is as a counter of the elements, if you want to identify the first, just to see $ index == 0?
You need to call an event, whichever you need, and then capture the $index for example using ng-click:
<ion-header-bar>
Showing at {{distance.current_scroll_distance}}
</ion-header-bar>
<ion-list>
<ion-item collection-repeat='results in data.results'>
<div ng-click="captureElemnt($index)">{{result.name}} / {{result.distance}}</div>
</ion-item>
</ion-list>
js:
$scope.captureElement = function(index){
if (index == 0){
//do whatever you need
}
}