Ionic3 coding- trying to retrieve quote of the day - json

Code in provider.ts file :
getQuotes() : Observable<any> {
return this.http.get("");
}
1st method: The coding in home.ts file of the page where the quote needs to be displayed:
quote:string;
author:string;
constructor(public navCtrl: NavController, private qp: QuoteProvider) { }
ionViewDidLoad()
{
this.qp.getQuotes().subscribe(data => {
this.quote = data.quote;
this.author = data.author;
});
}
.html code tried this nothing worked:
<h2> {{ quote}} </h2>
<h3> {{ author }}</h3>
</ion-item> </ion-list>
2nd method tried; tried using array though the data is not in array format
home.ts file:
export class HomePage { quote:any[]; author:any[];
constructor(public navCtrl: NavController, private qp: QuoteProvider) { }
ionViewDidLoad() {
this.qp.getQuotes().subscribe(data => {
this.quote = data.quotes;
this.author = data.quotes;
});
}
.html file code*:
<ion-list>
<ion-item *ngFor = "let q of quote">
<h2> {{ q.quote}} </h2>
<h3> {{q.author }}</h3>
</ion-item>
</ion-list>

In provider.ts you should do the following:
import 'rxjs/add/operator/map';
getQuotes(){
return this.http.get("").map(res => res.json());
}
Then in home.ts
ionViewDidLoad()
{
this.qp.getQuotes().subscribe(data => {
this.quote = data.contents.quotes[0].quote;
this.author = data.contents.quotes[0].author;
// This is assuming the quotes array always has only one quote
});
}
EDIT
As Prerak Tiwari commented, you also need to remove the for loop in home.html:
<ion-list>
<ion-item>
<h2> {{ quote }} </h2>
<h3> {{ author }}</h3>
</ion-item>
</ion-list>

Related

Print JSON response from REST api in ionic

I'm trying to print a JSON response that I get from a RESTful API request like that:
products:Observable<any>;
constructor(public navCtrl: NavController, private backgroundGeolocation: BackgroundGeolocation, public zone: NgZone, private auth: AuthService, public httpClient: HttpClient)
{
this.products = this.httpClient.get('http://127.0.0.1:8000/product');
}
It works fine, indeed if I print result in console:
this.products
.subscribe(data => {
console.log('my data: ', data);
});
the data is right.
But now, I don't know how to print them out onto a HTML page. I've tried this but it doesn't work:
<ion-list>
<ion-item *ngFor="let p of (products | async)?.results">{{ p.productName}}
</ion-item>
</ion-list>
Are there other ways to resolve the problem?
My JSON response is like that:
0: Object { idProduct: "1", productName: "Pasta", purchased: "0" }
​
1: Object { idProduct: "2", productName: "latte", purchased: "0" }
I have resolved the trouble. I want to post the solution to help other users in this bad situation.
Solution is so simple. I created a new typescript file called: 'rest-service' made up by:
#Injectable()
export class RestServiceProvider {
constructor(public http: HttpClient) {
console.log('Hello RestServiceProvider Provider');
}
getUsers() {
return new Promise(resolve => {
this.http.get('http://127.0.0.1:8000/product').subscribe(data => {
resolve(data);
}, err => {
console.log(err);
});
});
}
}
Now, in home.ts I've done that:
getUsers() {
this.restProvider.getUsers()
.then(data => {
this.products = data;
console.log(this.products);
});
}
And then, in the constructor, that:
this.getUsers();
In HTML side instead, the solution is very very simple:
<ion-item *ngFor="let p of products"> {{ p.productName }}
However, thanks to all
please try to convert products to array object. That may fix your problem.
this.products = this.products.json();
UPDATE
Looks like you found the solution. Normally I don't prefer doing *ngFor directly at a function
<!-- DON'T DO THIS -->
<ion-item *ngFor="let item of someFunction()">
but rather define a variable above the constructor, and then assign data. A separate file wouldn't be necessary, but can be useful if you are doing the same request over and over.
TypeScript
items: Array<any> = [];
constructor() {
// ...
}
ionViewDidLoad() {
this.http.get('https://someurl.com/data').subscribe((data: any) => {
this.items = data;
}).catch(err => console.error('Something went wrong: ', err));
}
HTML
<ion-item *ngFor="let item of items">
{{ item.name }}
</ion-item>
Old answer
What happens if you just do following?
<ion-item *ngFor="let p of products">
Any reason why you are trying to access .results on the products-array?
If you get any errors in the console, please share them with us.

Error While Trying to Display Value from Jsonobject in ionic 3?

Hello guys this may be dumb question but am new for ionic development , am facing problem while trying to display values from jsonobject,now let me explain in detail am fetching jsonobject from webservice and need to display it and i have successfully fetched the value from service but couldn't be able to display it while am trying am getting Cannot ready property 'StatusName 'undefined now let me post what i have tried so far :
This is my json getting from service:
{
"StatusName": "Open",
"ApprovalStatusName": "Awaiting Approval",
"CreatedByName": "Mark (Marx)",
"LastModifiedByName": "Mark (Marx)",
"ContractID": 20,
"ContractCode": "PIL",
}
And this is the typescript page:
export class ContractApprovalViewPage {
private contracts :any;
private contracttype:any;
private results:any;
constructor(public navCtrl: NavController, public navParams: NavParams,public contractApprovalViewService:ContractApprovalViewService ) {
this.contracts=this.navParams.get('result');
this.getContractApprovalView(this.contracts);
}
getContractApprovalView(contracttype){
this.contractApprovalViewService.getContractApproval(contracttype).then(data => {
//console.log(data);
this.results=data;
console.log(this.results);
console.log(this.results.CustomerName);
});
}
}
This is my service Page:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Events } from 'ionic-angular';
import 'rxjs/add/operator/map';
#Injectable()
export class ContractApprovalViewService {
private _result;
constructor(public http: Http, public events: Events) { }
getContractApproval(contracttype:any) {
return new Promise(resolve => {
this.http.get('http://172.16.6.187/sf/api/cnrt/getContractapprovalview/'+ contracttype.Column0 +'/C').subscribe(
data => {
// console.log('http://xxxx/xx/xx/'+ contracttype.Column0 +'/C');
this._result = data;
resolve(JSON.parse(this._result._body));
},
err => {
this._result = err;
// this.events.publish("message:error", JSON.parse(this._result._body));
}
);
});
}
}
This is my html Page:
<ion-header>
<ion-navbar>
<ion-title>Approval</ion-title>
</ion-navbar>
</ion-header>
<ion-content >
<ion-list no-padding>
<ion-card>
<ion-item >
{{results.StatusName}}
</ion-item>
</ion-card>
</ion-list>
</ion-content>
Don't know where am making mistake how someone teach me where am wrong, Thanks in advance !
First declare variable above constructor
statusName:string;
then in below function
getContractApprovalView(contracttype){
this.contractApprovalViewService.getContractApproval(contracttype).then(data => {
//console.log(data);
this.results=data;
console.log(this.results);
this.statusName = this.results.statusName;
//this.results.statusName status name key should match the response you are getting.
console.log(this.results.CustomerName);
});
}
}
now in html
just print status name
as you are not passing array so dont use results.statusname
<ion-content >
<ion-list no-padding>
<ion-card>
<ion-item >
{{statusName}}
</ion-item>
</ion-card>
</ion-list>
</ion-content>

Ionic 2 will not let me loop over an object of objects using *ngFor

I am developing an app where users can search for classified ads.
However, I am unable to display the search results.
Here is my search_results.ts:
import {Component} from '#angular/core';
import {NavController, NavParams} from 'ionic-angular';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'page-page1',
templateUrl: 'search_results.html' })
export class SearchResults {
public term: any;
public ads: any;
public tmp: any;
constructor(public navCtrl: NavController, public params: NavParams, public http: Http) {
this.term = this.params.get('term');
this.ads = [];
this.tmp = [];
console.log("this.term", this.term);
this.http.get('http://www.truckers.host/app/search-ads.php')
.map(res => res.json()).subscribe(data => {
console.log("this is returned from http.get", data);
});
}
ngOnInit() {
// Let's navigate from TabsPage to Page1
console.log(this.params);
} }
Now, in my search_results.html to display the search results, I am not getting anything to print.
Here is that code:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>
<img src="assets/images/trucker-to-trucker-logo.png" />
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="card-background-page">
<ion-card>
<ion-card-header>
Search Results
</ion-card-header>
<ion-card-content>
Searching for: <b>{{ term }}</b>
</ion-card-content>
</ion-card>
<ion-card>
<ion-list>
<ion-item *ngFor="let ad of ads">
{{ ad.ad_id }}
</ion-item>
</ion-list>
</ion-card>
</ion-content>
Nothing is returned, or iterated over.
When I console.log(data), I get an Object of Objects, and Ionic does not want to loop them.
Please let me know what other information I should include to help.
*ngFor only supports for Array and not Json Object.
You should consider using a custom Pipe to convert Object to Array.
Documentation about Pipe.
#Pipe({name: 'toArray'})
export class ToArrayPipe implements PipeTransform {
transform(inputObj: any, arg: any) {
if (!inputObj) { return [] }
let arr = [];
for(let key in inputObj) {
// Option1 (only value without the json object's key)
// this way will lose the key of Json Object
//arr.push(inputObj[key]);
// OPtion2 (both the key and value)
let obj = {};
obj[key] = inputObj[key];
arr.push(obj);
}
return arr;
}
}
Then add it to declarations of NgModule, and use it in your temple this way:
<ion-item *ngFor="let ad of ads | ToArray">
...
</ion-item>

Filter JSON by specific value ionic 2

im new in IOnic 2 and Angular, i try to filter a Json to show only a especific value; example get only user by gender. this is my code
home.html
<ion-list>
<ion-item *ngFor="let item of items | filter: {item.gender:'female'}" (click)="itemClicked($event,item)">
<ion-avatar item-left>
<img src="{{item.picture.thumbnail}}">
</ion-avatar>
<h2>{{item.name.first | uppercase }}</h2>
<h3>{{item.name.last | uppercase }}</h2>
<p>{{item.gender}}</p>
<button ion-button item-right color="danger" (click)="buttonClick($event)">Button</button>
</ion-item>
</ion-list>
This is my .ts file with the API Service
import { Component } from '#angular/core';
import {Http} from '#angular/http';
import { NavController } from 'ionic-angular';
import 'rxjs/add/operator/toPromise';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public items:any;
constructor(public navCtrl: NavController,public http: Http) {
this.http = http;
this.http.get("http://api.randomuser.me/?results=10")
.subscribe(data =>{
//console.log(data['_body']);
this.items=JSON.parse(data['_body']).results;//Bind data to items object
},error=>{
console.log(error);// Error getting the data
} );
}
buttonClick(event){
console.log("button clicked");
console.log(event);
}
itemClicked(event,itemData){
console.log("item clicked");
console.log(event);
console.log(itemData);
}
}
But my idea does not work
any idea to help me-?? :`/
You can do that in the component code instead of in the view...
import { Component } from '#angular/core';
import {Http} from '#angular/http';
import { NavController } from 'ionic-angular';
import 'rxjs/add/operator/toPromise';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public items: any;
constructor(public navCtrl: NavController, public http: Http) {
// this.http = http; <- You don't need this, this.http is already available because by declaring it in the constructor, now a public property is created in the component
this.http.get("http://api.randomuser.me/?results=10")
.map(data => data.json().results) // Instead of getting the _body manually, you can use the map method from RxJS
.subscribe(data =>{
//console.log(data);
this.items = data.filter(item => item.gender === 'female');
},error=>{
console.log(error);// Error getting the data
});
}
// ...
}
And now in your view
<ion-list>
<ion-item *ngFor="let item of items" (click)="itemClicked($event,item)">
<ion-avatar item-left>
<img src="{{ item.picture.thumbnail }}">
</ion-avatar>
<h2>{{ item.name.first | uppercase }}</h2>
<h3>{{ item.name.last | uppercase }}</h2>
<p>{{ item.gender }}</p>
<button ion-button item-right color="danger" (click)="buttonClick($event)">Button</button>
</ion-item>
</ion-list>

Angular2: EXCEPTION: Attempt to use a dehydrated detector: QuizzPage_2 -> select

I'm having an issue in my ionic2/angular2 app.
I'm building a quizz app, in which the user is prompted to answer questions, on radio choices.
The moment the first choice is made, I get this error:
EXCEPTION: Attempt to use a dehydrated detector: QuizzPage_2 -> select
The console:
The code breaks here when I debug Pause On Exception:
SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err;
Here are my main files:
The page.html:
(...)
<ion-item radio-group *ngFor="#choice of quizz.getChoices()">
<ion-label>
<p courant>{{ choice }}</p>
</ion-label>
<ion-radio (click)="onSubmit($event, choice)">
{{ choice }}
</ion-radio>
</ion-item>
(...)
My page.ts:
import {Page, NavController, NavParams} from 'ionic-angular';
import {Quizz} from '../models/quizz';
import {QuizzResultsPage} from './quizz-results.page';
import quizzes from '../../data/quizzes';
#Page({
templateUrl: 'build/pages/quizz/Quizzes/templates/quizz.page.html',
})
export class QuizzPage {
nav;
quizz;
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
// Load the quizz with passed topicId from the params.get (import{NavParams})
this.quizz = this.loadQuizz(params.get('topicId'));
}
loadQuizz(topicId) {
// cont quizz = data (import quizzes from '../../data/quizzes';)
const quizz = quizzes.filter((quizz) => {
return quizz.topicId === topicId;
})[0];
return new Quizz(quizz);
}
onSubmit(event, answer) {
this.quizz.submitAnswer(answer);
if (this.quizz.isCompleted) {
this.nav.push(QuizzResultsPage, {
quizz: this.quizz
});
}
}
}
I'm still able to finish the quizz, but in the end in my result page, I can't go back or restart the quizz, and my navbar breaks...
My resultpage.html:
(...)
<ion-card-content>
<p>
Votre score:
<span primary>{{ quizz.getScore() }}</span> / <b>{{ quizz.getGradingScale() }}</b>
</p>
</ion-card-content>
</ion-card>
<!-- Questions with answers -->
<div [hidden]="quizz.isPerfect()">
<ion-card *ngFor="#i of quizz.items" style="background-color:aliceblue;">
<ion-card-header>
<b bluegray text-uppercase>Question: </b>
<p>
{{ i.question }}
</p>
</ion-card-header>
<ion-card-content>
<b bluegray text-uppercase>Réponse:</b>
<p courant text-justify>{{ i.answer }}</p>
</ion-card-content>
</ion-card>
</div>
<!-- Exit & Restart -->
<div padding style="width:70%; margin: 0 auto">
<button item-right block (click)="onHomeClicked($event)">Recommencer
<ion-icon name="refresh-circle"></ion-icon>
</button>
<button itel-left block (click)="onGoHome($event)">Accueil
<ion-icon name="home"></ion-icon>
</button>
</div>
</ion-content>
And finally my results.ts:
import {Page, NavController, NavParams} from 'ionic-angular';
import {TopicsPage} from '../../topics';
import {Home} from '../../../home/home';
#Page({
templateUrl: 'build/pages/quizz/Quizzes/templates/quizz-results.page.html',
})
export class QuizzResultsPage {
nav;
quizz;
constructor(nav: NavController, params: NavParams) {
this.quizz = params.get('quizz');
this.nav = nav;
this.nav.pop();
}
onHomeClicked(event) {
this.nav.setRoot(TopicsPage);
this.nav.pop(TopicsPage);
}
onGoHome(event){
this.nav.setRoot(Home);
this.nav.pop(Home);
}
Someone have an idea? Thanks