Hi,
I’m still new to Ionic 2 so I hope you guys can help me. I have an App and it has a list from a JSON file, all works fine. However, it pushes to a new page where I want the rest of the JSON data for that item to show.
How do I use the item passed via the URL to then get the data just for that item?
items-basic.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { NavController } from 'ionic-angular';
/* Page Imports */
import { DetailsBasic } from '../details-basic/details-basic';
@Component({
selector: 'page-items-basic',
templateUrl: 'items-basic.html'
})
export class ItemsBasic {
items
constructor(public navCtrl: NavController, private http: Http) {
this.http.get("assets/data/basic.json").subscribe (data => {
this.items = JSON.parse(data['_body']).results;
}, error => {
console.log(error);
})
}
itemClicked(event, item) {
this.navCtrl.push(DetailsBasic, {
item: item
});
}
}
items-basic.html
<ion-header>
<ion-navbar color="primary">
<ion-title>Basic Items</ion-title>
</ion-navbar>
</ion-header>
<ion-content class="items-basic" padding>
<ion-list>
<ion-item *ngFor="let item of items" (click)="itemClicked($event, item)">
<ion-thumbnail item-left>
<img src="assets/img/items/{{item.image}}.png">
</ion-thumbnail>
<h1>{{item.name}}</h1>
<p>{{item.disc}}</p>
<ion-icon item-right name="arrow-forward"></ion-icon>
</ion-item>
</ion-list>
</ion-content>
items-details.ts and items-details.html (DetailsBasic class) is where the items click though to and that’s where i want the data from the JSON file to show the data for the item that has been clicked
You’re on the right track. Inside your itemClicked function push the new page and pass the data like this:
this.navCtrl.push(ItemDetailClass, { item: item });
then in your itemdetail page retrieve the data from the nav parameters like this:
this.item = navParams.get(‘item’);
Make sure you’ve imported the NavParams in your detail component and also added it in your constructor.
1 Like
Thanks, iv got it passing the id of the item (item.id )
this is what i have on items-details.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { NavController, NavParams } from 'ionic-angular';
@Component({
selector: 'page-details-basic',
templateUrl: 'details-basic.html'
})
export class DetailsBasic {
items
state: string = "craft";
constructor(public navCtrl: NavController, public navParams: NavParams, private http: Http) {
this.items = navParams.get('item');
this.http.get("assets/data/basic.json").subscribe (data => {
this.items = JSON.parse(data['_body']).results;
}, error => {
console.log(error);
})
}
ionViewDidLoad() {
console.log('Hello DetailsBasic Page');
}
}
but i’m getting an error
error_handler.js:47 EXCEPTION: Error in ./DetailsBasic class DetailsBasic - inline template:11:12 caused by: Cannot find a differ supporting object '2' of type 'string'. NgFor only supports binding to Iterables such as Arrays.ErrorHandler.handleError @ error_handler.js:47next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
error_handler.js:49 ORIGINAL EXCEPTION: Cannot find a differ supporting object '2' of type 'string'. NgFor only supports binding to Iterables such as Arrays.ErrorHandler.handleError @ error_handler.js:49next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
error_handler.js:52 ORIGINAL STACKTRACE:ErrorHandler.handleError @ error_handler.js:52next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
error_handler.js:53 Error: Cannot find a differ supporting object '2' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
at NgFor.ngOnChanges (ng_for.js:128)
at DebugAppView._View_DetailsBasic0.detectChangesInternal (DetailsBasic.ngfactory.js:363)
at DebugAppView.AppView.detectChanges (view.js:271)
at DebugAppView.detectChanges (view.js:376)
at DebugAppView.AppView.detectViewChildrenChanges (view.js:297)
at DebugAppView.AppView.detectChangesInternal (view.js:282)
at DebugAppView.AppView.detectChanges (view.js:271)
at DebugAppView.detectChanges (view.js:376)
at ViewRef_.detectChanges (view_ref.js:130)
at Tab.NavControllerBase._viewInsert (nav-controller-base.js:387)ErrorHandler.handleError @ error_handler.js:53next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
error_handler.js:56 ERROR CONTEXT:ErrorHandler.handleError @ error_handler.js:56next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
error_handler.js:57 DebugContext {_view: _View_DetailsBasic0, _nodeIndex: 13, _tplRow: 11, _tplCol: 12}ErrorHandler.handleError @ error_handler.js:57next @ application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:119onHandleError @ ng_zone_impl.js:64t.handleError @ polyfills.js:3e.runGuarded @ polyfills.js:3NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26t.invokeTask @ polyfills.js:3e.runTask @ polyfills.js:3invoke @ polyfills.js:3
polyfills.js:3 Uncaught Error: Error in ./DetailsBasic class DetailsBasic - inline template:11:12 caused by: Cannot find a differ supporting object '2' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
items-details.html
<ion-list>
<ion-item *ngFor="let item of items">
<ion-thumbnail item-left>
<img src="assets/img/items/{{item.image}}.png">
</ion-thumbnail>
<h1>{{item.name}}</h1>
<p>{{item.disc}}</p>
<p>{{item.crafting.one}}</p>
<p>{{item.crafting.two}}</p>
<p>{{item.crafting.three}}</p>
<ion-icon item-right name="arrow-forward"></ion-icon>
</ion-item>
</ion-list>
First you declare this.items = navParams.get(‘item’);
That means the value of the navparams is assigned to this.items. That’s what is causing the error, since ngFor can’t loop over a string. BTW don’t do any http calls inside your constructor. Rather define another function outside your constructor. Even better, define your calls inside a (shareable) service. Also this: this.items = JSON.parse(data[’_body’]).results; isn’t really necessary. Just do this.items = data.json() and it will automagically get the right results for you.
1 Like
Ok, so if i change my items-details.html to:
<ion-list>
<ion-item>
<ion-thumbnail item-left>
<img src="assets/img/items/{{items.image}}.png">
</ion-thumbnail>
<h1>{{items.name}}</h1>
<p>{{items.disc}}</p>
<ion-icon item-right name="arrow-forward"></ion-icon>
</ion-item>
</ion-list>
i changed item to items, becuase with item i got
EXCEPTION: Error in ./DetailsBasic class DetailsBasic - inline template:15:8 caused by: Cannot read property 'name’
ORIGINAL EXCEPTION: Cannot read property ‘name’ of undefined
items-details.ts
export class DetailsBasic {
items
constructor(public navCtrl: NavController, public navParams: NavParams, private http: Http) {
this.items = navParams.get('item');
this.http.get("assets/data/basic.json").subscribe (data => {
this.items = data.json().results;
}, error => {
console.log(error);
})
}
With this i don’t get errors anymore but i don’t get any content either.
I will change the HTTP to a service after i get it working, i just thought it would be easier to get it all working first then put the JSON file in a service.
CarlRyds:
this.http.get(“assets/data/basic.json”).subscribe (data => {
this.items = data.json().results;
}, error => {
console.log(error);
})
This isn’t going to work. Just do this:
this.http.get("assets/data/basic.json").subscribe (data => {
this.items = data.json();
console.log(this.items)
}, error => {
console.log(error);
})
lose the .results, unless its nested inside a results property. Log the entire data to your console to see if everythings there.
1 Like
the console is showing its getting all the items, i.e the whole json file, not just the item with the id
Fixed it
You don’t need any of the JSON data on the items-details.ts because it’s already passing the JSON data thought the navParms.
Thanks for your help mate, it made me think about it properly, your a star mate.
Yes… exactly. You have the list, then you pass the entire object through the navparams already. Glad you figured it out! My first answer:
You’re on the right track. Inside your itemClicked function push the new page and pass the data like this:
this.navCtrl.push(ItemDetailClass, { item: item });
then in your itemdetail page retrieve the data from the nav parameters like this:
this.item = navParams.get(‘item’);
Make sure you’ve imported the NavParams in your detail component and also added it in your constructor.
already told you so
1 Like
Hello sir, i just did what you said but i cannot get any data from JSON, it is always ‘undefined’.
Hello, what if I want to add a “next” that will fetch the next data into the “details page” without going back to the lists?