Ionic 2 Fetching Data From Nested Arrays - arrays

I am new to Ionic 2 / Angular 2 and I have been trying to fix a simple issue for an app I am building but have found no solution so far.
I am simply trying to fetch data from a json file to list a number of categories (film titles) and display more detail (production details) into a detail page. The details (director and producer) are nested within an array (production) in the json file.
Although I am able to fetch the film tiles from the json file, I am not able to accesss and display the data from the nested array once the detail page is open.
I have tried a lot of different things (including looping through the array using for Each, creating a production object) but nothing seems to be working. Unless I am missing something very obvious?
Can someone please help?
Thanks in advance! (I will be eternally grateful for any response.)
home.ts
export class HomePage {
films: any;
productions: any;
constructor(public navCtrl: NavController, public http: Http) {
this.films = this.http.get("assets/data/results-data.json").map(res => res.json());
}
openDetails(film) {
this.navCtrl.push('FilmDetailsPage', {film: film});
}
}
home.html
<ion-list>
<button ion-item *ngFor="let film of films.results" (click)="openDetails(film)">
{{ film.title }}
</button>
</ion-list>
results-data.json (extract)
{
"results": [
{
"title": "A New Hope",
"production": [
{
"director" : "George Lucas",
"producer" : "Rick McCallum"
}
]
},
{
"title": "Attack of the Clones",
"production": [
{
"director": "George Lucas",
"producer": "Kurtz"
}
]
},
film-detail.html
<ion-header>
<ion-navbar color="primary">
<ion-title>{{ film.title }}</ion-title> // Working
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-card>
<ion-card-content>
**{{ production.director }} // Not working**
</ion-card-content>
</ion-card>
</ion-content>
film-detail.ts
export class FilmDetailsPage {
film: any;
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.film = this.navParams.get('film');
}
}

Can you try this, I think there is a problem with your path:
film-detail.html
<ion-header>
<ion-navbar color="primary">
<ion-title>{{ film.title }}</ion-title> // Working
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-card>
<ion-card-content>
{{ film.production[0].director }}
</ion-card-content>
</ion-card>
</ion-content>

To make ajax request in angular
this.http.get("assets/data/results-data.json").subscribe(data => {
// Read the result field from the JSON response.
this.films = data['results'];
});

You Should try this:
<ion-content padding>
<ion-card>
<ion-card-content>
{{ film.production[0]?.director }}
</ion-card-content>
</ion-card>
</ion-content>
I was having the same problem but I solved my problem by using the above code. And it renders the html first so that's why error and by using the ?, it will solve the problem.

Related

Get value from each *ngFor ionic 4, ionic 5, ionic 6

I have the following code:
<ion-item *ngFor="let box of boxes">
This will show results from array:
On the .ts file i have the following:
isApproved : boolean;
public box: any;
This will generate from boxes array:
box1 -> [id, name, isApproved]
box2 -> [id, name, isApproved]
box3 ->[id, name, isApproved]
I need to get the isApproved value of each box, so when i activate the toggle, isApproved will change in database.
I know one method that doesn't fits my needs, like clicking and getting the id from route but i want to open a new page for that.
Just put and ngModel in the ion-toggle:
html:
<ion-item *ngFor="let box of boxes">
<ion-avatar slot="start"></ion-avatar>
<ion-label>...</ion-label>
<ion-toggle [(ngModel)]="box.isApproved" (ionChange)="approvedToggled($event)"></ion-toggle>
</ion-item>
ts:
approvedToggled(event, box) {
if(event.detail.value) {
// save to box to database
}
/* or:
if(item.isApproved) {
// save to database
}
*/
}
The solution is very simple.
The working code is:
On my HTML:
<div *ngFor="let box of boxes">
<ion-item-sliding id="anyId">
<ion-item>
<ion-avatar slot="start">
<img [offset]="100" [alt]="box.user?.name"
defaultImage="./assets/img/photo.png" [lazyLoad]="box.user?.photo?.url()" />
</ion-avatar>
<ion-label class="ion-text-wrap">
<ion-text color="dark">
<h3 class="bold no-margin">
{{ box.user?.name }}
</h3>
</ion-text>
</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="primary" (click)="onDelete(box)">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</div>
On my TS i have:
Importing service:
import { Box } from '../../services/box-service';
Before constructor:
public boxes: Box[] = [];
public box: Box;
constructor(private BoxService: Box) {
super(injector);
}
Loading boxes from service:
async loadDataFromService() {
try {
const boxes = await this.boxService.loadBoxes(this.params);
for (let box of boxes) {
this.boxes.push(box);
}
this.onRefreshComplete(boxes);
} catch {
}
}
... this will return an array with arrays. Each array has an object.
Now we just access each box from HTML (click)="onDelete(box)"
async onDelete(box: Box) {
await Swal.fire({
title: 'Are you sure?',
text: 'Blah, blah',
icon: 'warning',
iconColor: '#5038de',
showCancelButton: true,
confirmButtonColor: '#5038de',
cancelButtonColor: '#e0b500',
confirmButtonText: 'Yes',
cancelButtonText: 'No',
heightAuto: false,
showClass: {
popup: 'animated fade-in'
},
hideClass: {
popup: 'animated fade-out'
}
}).then(async (result) => {
if (result.value) {
await this.boxService.deleteBox(box)
this.goTo()
} else {
this.goTo()
}
});
}
}
Resuming, the solution for:
<ion-item *ngFor="let box of boxes">
<ion-avatar slot="start"></ion-avatar>
<ion-label>...</ion-label>
<ion-toggle (ionChange)="myFunction(box)"></ion-toggle>
</ion-item>
was simply (ionChange)="myFunction(box)" or (click)="myFunction(box)"
In my case box will be an entire object, passing the id will be enough to perform any action.

ionic 2 local storage get and display the data

hi i cant access my data in localstorage , it always gives me error . i need help in displaying my datas in my home . thank you for your help :)
Error:
Typescript Error
Argument of type 'Promise' is not assignable to parameter of type 'string'.
this.user = JSON.parse(this.storage.get(this.key));
prompt.present();
Typescript
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ViewController, AlertController } from 'ionic-angular';
import {Storage} from '#ionic/storage';
/**
* Generated class for the CrudPage page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-crud',
templateUrl: 'crud.html',
})
export class CrudPage {
user: any = [] ;
key: any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController,
public alertCtrl: AlertController,
public storage: Storage) {
this.storage.forEach( (value) => {
this.user.push(value);
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad CrudPage');
}
add() {
let prompt = this.alertCtrl.create({
title: 'Add User',
message: "Enter information of the user",
inputs: [
{
name: 'name',
placeholder: 'name'
},
{
name: 'password',
placeholder: 'password'
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked!');
}
},
{
text: 'Save',
handler: data => {
let key = data.name + data.password;
this.storage.set(key, JSON.stringify(data));
console.log(data);
}
}
]
});
this.user = JSON.parse(this.storage.get(this.key));
prompt.present();
}
delete(key){
this.storage.remove(key);
}
update(key){
}
}
HTML
<!--
Generated template for the CrudPage page.
See http://ionicframework.com/docs/components/#navigation for more info on
Ionic pages and navigation.
-->
<ion-header>
<ion-navbar>
<ion-title>Crud</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button ion-button clear icon-start color="dark" (click)="add()">
<ion-icon name="add-circle">Add User</ion-icon>
</button>
<br>
<ion-grid text-center>
<ion-row>
<ion-col width-100>
USERS
</ion-col>
</ion-row>
<ion-row>
<ion-col width-33>
<strong>User Name</strong>
</ion-col>
<ion-col width-33>
<strong>Password</strong>
</ion-col>
<ion-col width-33>
<strong>Action</strong>
</ion-col>
</ion-row>
<ion-row *ngFor="let users of user" text-center>
<ion-col width-33>
<p>{{users.name}}</p>
</ion-col>
<ion-col width-33>
<p>{{users.password}}</p>
</ion-col>
<ion-col width-33>
<button ion-button clear icon-start color="dark" (click)="delete(users.name+users.password)">
<ion-icon name="trash"></ion-icon>
</button>
<button ion-button clear icon-start color="dark" (click)="update(users.name+users.password)">
<ion-icon name="create"></ion-icon>
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
Please help :) Thank you very much :)
this.storage.get(this.key) returns a promise, you have to do that:
this.storage.get(this.key).then(value => {
this.user = JSON.parse(value);
});
https://ionicframework.com/docs/storage/

How to retrieve data from a multi level object in Ionic 3?

This page works likes the following. The user selects a product (C2, Coca Cola, etc.) then the prices from the different supermarket are supposed to be displayed. This is the object I created.
productPrices = [
{
name: "C2 Green Tea",
prices: [
{
smPrice: 19.15,
tsPrice: 19.25,
rbPrice: 19.10
}
],
stock: 50
},
{
name: "Coca Cola",
prices: [
{
smPrice: 21.50,
tsPrice: 21.45,
rbPrice: 24.50
}
],
stock: 50
},
{
name: "Nature's Spring",
prices: [
{
smPrice: 12.50,
tsPrice: 11.50,
rbPrice: 13.00
}
],
stock: 50
},
{
name: "Red Horse Beer",
prices: [
{
smPrice: 31.50,
tsPrice: 29.50,
rbPrice: 30.90
}
],
stock: 50
},
];
getProductPrice(product: string){
return this.productPrices.filter(item => item.name == product);
}
By using the getProducPrice() method, I'm able to get the product selected and its properties. But I can't get the value of the prices. What I have on the template page is this.
<div *ngFor="let itemPrice of productPrices">
<div *ngFor="let marketPrice of itemPrice.prices">
<form (ngSubmit)="onFormSubmit(userForm)" #userForm="ngForm" >
<ion-list>
<ion-list-header>
Supermarkets
</ion-list-header>
<ion-item>
<ion-thumbnail item-start>
<img src="assets/grocery/market-logo/ts.jpg">
</ion-thumbnail>
<p>{{marketPrice.tsPrice}}</p>
<button ion-button clear item-end (click)="onBuy()" >Buy</button>
</ion-item>
<ion-item>
<ion-thumbnail item-start>
<img src="assets/grocery/market-logo/sm.png">
</ion-thumbnail>
<p>{{marketPrice.smPrice}}</p>
<button ion-button clear item-end (click)="onBuy()"> Buy</button>
</ion-item>
<ion-item>
<ion-thumbnail item-start>
<img src="assets/grocery/market-logo/rb.jpg">
</ion-thumbnail>
₱<input name="price" value="{{marketPrice.rbPrice}}">
<p>{{marketPrice.rbPrice}}</p>
<button ion-button clear item-end (click)="onBuy()">Buy</button>
</ion-item>
<ion-item>
<ion-label>Enter Quantity</ion-label>
<ion-input type="number" min="0"></ion-input>
</ion-item>
</ion-list>
</form>
</div>
</div>
The problem with that is that if I use a form to submit, it'll submit all the values including the prices of the other supermarkets.
Is there a better way for me to loop from the object I received and access the prices values of each product? I'm not using a DB nor is this file saved in a json file. I just want to know if there's a better way to get values at the typescript file by using some methods. Thank you.
try this you will property of selected product
<div *ngFor="let item of productPrices">
<button (click) ="getProductPrice(item)">get</button>
</div>
In your ts file
getProductPrice(product: any){
console.log(product);
}

Page doesn't open on clicking in side menu - ionic 2 app

I am unable to open a page upon clicking it in side menu.
This is my app.component.ts:
this.pages = [
{ title: 'NFC Page', component: NfcPage, note: 'NFC Page' },
{ title: 'Student Details', component: StudentDetails, note: 'Student Details' },
];
This is my app.module.ts:
#NgModule({
declarations: [
StudentDetails,
NfcPage,
],
entryComponents: [
StudentDetails,
NfcPage,
],
This is my nfc.ts page:
import {Component} from '#angular/core';
import {IonicPage, NavController, NavParams} from 'ionic-angular';
import {NFC, Ndef} from '#ionic-native/nfc';
#IonicPage()
#Component({
selector: 'page-nfc',
templateUrl: 'nfc.html',
})
export class NfcPage {
constructor(public navCtrl: NavController,
public navParams: NavParams,
private nfc: NFC,
private ndef: Ndef) {
}
}
This is my nfc.html page:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>NFCPage</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p>NFC Page!</p>
</ion-content>
Student details page opens fine but when I click "Nfc page", nothing happens.
for open the page through the side menu you need to make that page as a rootpage when you click on the side menu option.You may find the below code:-
app.html:
<ion-menu id="myMenu" [content]="mycontent" >
<ion-content>
<ion-list>
<ion-item ion-item small menuClose (click)="nav.setRoot(pages.nfc)">
<ion-icon name="home" item-left menuClose ></ion-icon> NFC
</ion-item >
<ion-item small menuClose (click)="nav.setRoot(pages.std_detils)">
<ion-icon ios="ios-contact" md="ios-contact" item-left ></ion-icon> Student Details
</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav #mycontent [root]="rootPage"></ion-nav>
app.component.ts:
this.rootPage = NfcPage;
this.pages = {
"nfc": NfcPage,
"std_detils": StudentDetails,
};
I have managed to find a solution. The problem is in the constructor of nfc.ts module. The two private parameters (private nfc: NFC and private ndef: Ndef) seem to be broken from the plugin that I am using. I removed these two parameters from the constructor and I was able to open the page. Sadly there was no exception thrown in the console or anywhere else. Hope it helps someone.

How to access Object in array using ng-repeat?

i´m having a problem with using ng-repeat. I´m using Ionic 2 with TypeScript and HTML5. I created an array of Objects where i need to access it´s attributes. It´s saying "cannot read property c.getAttribute of undefined" but when i tried to access these attributes not using ng-repeat (just typing array[0].getAttribute), everything worked fine.
Here is my code:
<ion-list>
<ion-item ng-repeat="c in card">
<ion-card class="styledRow">
<ion-item class="cardHeaderClass">
<font size="4" style="color:#FFFFFF;">{{c.getExpiration}}</font>
<p>Monthly student</p>
</ion-item>
<ion-item class="rangeSlider">
<p style="color:white">Perm</p>
<ion-badge color="blue" item-right>{{c.getPermValue}}/{{c.getTotalValue}}{{c.getDayEuro}}
</ion-badge>
</ion-item>
<ion-item class="rangeSlider">
<ion-range disabled="false" min="0" max="{{c.getTotalValue}}" step="1" [(ngModel)]="c.getPermValue" color="secondary">
<ion-icon range-left name="close" color="danger"></ion-icon>
<ion-icon range-right name="checkmark-circle-outline" color="secondary"></ion-icon>
</ion-range>
</ion-item>
<ion-row class="styledRow">
<ion-col>
<button ion-button icon-left color="#f4f4f4" clear small>
<ion-icon name="calendar"></ion-icon>
<div>Platnosť: {{c.getExpiration}}</div>
</button>
</ion-col>
</ion-row>
<div text-right="" class="styledRow">
<ion-note>Refreshed: 12.3.2017
</ion-note>
</div>
</ion-card>
</ion-item>
</ion-list>
And here is my typescript:
export class HomePage {
card: permCard[];
constructor(public navCtrl: NavController) {
this.card = new Array();
for (let i = 0; i < 2; i++){
this.card.push(new permCard("Name","Name", 33, 40, " "+"days", "12.2.2017"));
}
}
}
export class permCard{
private centerName: string;
private permName: string;
private permValue: number;
private totalValue: number;
private dayEuro: string;
private expiration: string;
constructor(public center_name: string, public perm_name: string, public perm_value: number, public total_value: number,
public day_euro: string, public expiration_date: string){
this.centerName = center_name;
this.permName = perm_name;
this.permValue = perm_value;
this.totalValue = total_value;
this.dayEuro = day_euro;
this.expiration = expiration_date;
}
get getCenterName(): string {
return this.centerName;
}
get getPermValue(): number {
return this.permValue;
}
get getPermName(): string {
return this.permName;
}
get getTotalValue(): number {
return this.totalValue;
}
get getDayEuro(): string {
return this.dayEuro;
}
get getExpiration(): string {
return this.expiration;
}
}
I don´t know, if the problem is in the array, but only the array.push worked for me for initialization of array. Please, do you have any idea, what should be the problem. TypeScript and angular is new for me, thanks.
how-to-access-object-in-array-using-ng-repeat
You cant. ng-repeat is angularjs (version 1) syntax.
Ionic 2 is built on top of angular 2.
The format for for loop in template is:
<ion-item *ngFor="let c of card">
<ion-card class="styledRow">
<!-- shortened for brevity -->
</ion-item>
Documentation ngFor

Resources