I have to do a mobile application for school and I choosed to use Ionic 2 for this.
I need to display the daily timetable/schedule. For this, I'm using our intranet's API which returns a json, for exemple :
{
"1": [],
"4": {
"matiere": "M4201",
"prof": "LANDRÉ Jérôme",
"salle": "H201",
"evaluation": "N",
"texte": null,
"commentaire": null,
"type": "td",
"fin": 7
},
"7": {
"matiere": "M4204",
"prof": "GOMMERY Patrice",
"salle": "H205",
"evaluation": "N",
"texte": null,
"commentaire": null,
"type": "tp",
"fin": 10
},
"13": {
"matiere": "",
"prof": "",
"salle": "****",
"evaluation": "N",
"texte": "PROJETS",
"commentaire": null,
"type": "CM",
"fin": 19
},
"16": [],
"19": [],
"22": []
}
I successfully retrieve this in my application, but I dont find how to display of list of this.
Here is my /home/home.ts script :
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Home } from '../../models/home';
import { HomeCours } from '../../providers/home-cours';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
cours: Home[]
constructor(public navCtrl: NavController, private HomeCours: HomeCours) {
HomeCours.load().subscribe(cours => {
console.log(cours)
})
}
}
My /models/home.ts :
/**
* Created by corentin on 17/03/2017.
*/
//récupère la liste des cours sur http://intranet.iut-troyes.univ-reims.fr/api/edtjour/< id de la personne qui consulte >
export interface Home {
matiere: string;
prof: string;
salle: string;
evaluation: string;
texte: string;
commentaire: string;
type: string;
fin: number;
}
My /providers/home-cours.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import { Home } from '../models/home';
/*
Generated class for the HomeCours provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class HomeCours {
coursApiUrl = 'https://api.corentincloss.fr/intranet/edt.php?id=';
constructor(public http: Http) {
console.log('Hello HomeCours Provider');
}
load(): Observable<Home[]> {
return this.http.get(`${this.coursApiUrl}closs006`).map(res => <Home[]>res.json());
}
}
and finally my home.html :
<ion-header>
<ion-navbar>
<ion-title>Mes cours</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Emploi du temps du jour.</h2>
<hr />
<ion-list>
<div ion-item *ngFor="let cour of cours">
<h2>{{ cour.matiere }}</h2>
</div>
</ion-list>
</ion-content>
I'm sure this is coming from the id ("1", "4", "7"...) but I don't find any way to search the datas in those arrays.
If you could help me please it would be great :D
Thank you :)
After you've obtained the data, you should assign it to a property in your class:
export class HomePage {
cours: Home[]
constructor(public navCtrl: NavController, private HomeCours: HomeCours) {
HomeCours.load().subscribe(cours => this.cours = cours);
}
}
You can't *ngFor object. You should make an array from object.
export class HomePage {
cours: Home[] = []
constructor(public navCtrl: NavController, private HomeCours: HomeCours) {
HomeCours.load().subscribe((data: any) => for (let key in data) this.cours.push({key: key, value: cours[key]}););
}
}
Finally found, I had to declare a new array named "cours".
Here is my cours.ts :
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { CoursService } from '../../providers/cours-service';
/*
Generated class for the Cours page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-cours',
templateUrl: 'cours.html',
providers: [CoursService]
})
export class CoursPage {
public cours: any;
public heures: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public coursService: CoursService) {
this.loadCours();
console.log(coursService);
}
loadCours(){
this.coursService.load()
.then(data => {
let cours = new Array();
for (let key in data) {
cours.push(data[key]);
}
this.cours = cours;
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad CoursPage');
}
}
And now it's perfectly working ! Thank you for your answers :)
Related
Currently i'm developing a web app which shows the Golden State Warriors (Basketball Team) Roster.
My main goal consists in filtering all players by position.
Positions are numbers ordered from 1 to 5.
My question would be: which could be the way to transform my http get request in order to obtain the point-guards (position === 1) ??
roster-data.service.ts
import { Injectable } from '#angular/core';
import { Player } from "../models/player";
import { environment } from "../../environments/environment";
import {HttpClient, HttpErrorResponse} from '#angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError, map, filter } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class RosterDataService {
private readonly devURL = environment.url;
constructor(private http: HttpClient) {
}
jSON_Server_ReadPointGuards():Observable<Player[]> {
return this.http.get<Player[]>(`${this.devURL}/roster_GoldenStateWarriors`).pipe(
map(players => players.filter((player:Player) => player.position === 1)
),
catchError(this.handleError)
);
}
And then my interface
player.ts
export interface Player {
fullName: string,
shirtNumber: string,
position: number,
height: string,
weight: number,
points: number,
rebounds: number,
assists: number,
blocks: number,
steals: number,
imageFile: string,
imageDescrip: string
}
players.component.ts
import { Component, OnInit, isDevMode } from '#angular/core';
import { RosterDataService } from "../../services/roster-data.service";
import { Player } from "../../models/player";
import { imgRoute } from "../../services/img-route.service";
#Component({
selector: 'app-players',
templateUrl: './players.component.html',
styleUrls: ['./players.component.scss'],
providers: [RosterDataService]
})
export class PlayersComponent implements OnInit {
public imageLocation:string;
public bases!: Player[];
public escoltas!: Player[];
public aleros!: Player[];
public alaPivots!: Player[];
public pivots!: Player[];
public getPlayers: Player[] = [];
constructor(private _rosterDataService: RosterDataService) {
this.imageLocation = imgRoute.path;
}
ngOnInit(): void {
this.dev_SuscribeAllPointGuards();
// this.dev_SuscribeAllShootingGuards();
// this.dev_SuscribeAllSmallForwards();
// this.dev_SuscribeAllPowerForwards();
// this.dev_SuscribeAllCenters();
}
dev_SuscribeAllPointGuards(){
this._rosterDataService.jSON_Server_ReadPointGuards().subscribe(
pointguards => {
this.bases = pointguards;
}
);
}
}
players.component.html
<section>
<article>
<h4 id="pointGuard">{{ "players.firstTitle" | translate }}</h4>
<div class="gallery">
<div [routerLink]="'/'+(base.fullName | removespaces)+'/'+base.shirtNumber" *ngFor="let base of bases;">
<figure><img src="{{imageLocation + base.imageFile}}" alt="{{base.imageDescrip}}" title="{{base.imageDescrip}}"></figure>
<section>
<h5>{{base.fullName}}</h5>
<h6>{{base.shirtNumber}}</h6>
<h6>{{base.points}}</h6>
<h6>{{base.rebounds}}</h6>
<h6>{{base.assists}}</h6>
<h6>{{base.blocks}}</h6>
<h6>{{base.steals}}</h6>
</section>
</div>
</div>
</article>
</section>
I am working on auto-verification otp ionic2. In that, SMS permission is applied and if device mobile number exists or read otp from sms then it switch directly to dashboard page for that i use a function called watchSMS() as shown in angular code but it gives an error (SMS is not defined).
Any help will be highly appreciated.
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, AlertController, Platform, LoadingController, ToastController, ViewController } from 'ionic-angular';
import { FormGroup, FormBuilder, FormControl, Validators } from '#angular/forms';
import { Network } from '#ionic-native/network';
import { CrudHttpProvider } from '../../providers/crud-http/crud-http';
import { SQLite, SQLiteObject } from '#ionic-native/sqlite';
import { ConstantVariable } from '../../app/constant-variable';
import { HomePage } from '../home/home';
// import { SMS } from '#ionic-native/sms';
import { Sim } from "#ionic-native/sim";
import { AndroidPermissions } from '#ionic-native/android-permissions';
declare var window: any;
declare var SMS:any;
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
public myForm: FormGroup;
public mobile: any;
public db_name: any;
public url_play_store: any;
public buttonDisabled: any;
public studname: any;
public tuition_name: any;
public prn: any;
public otp: any;
public api_key: any;
public userinfo:any;
public stored_mb:any;
public simInfo: any;
public cards: any;
public phoneNumber: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public formBuilder: FormBuilder, public alertCtrl: AlertController, public platform: Platform, public network: Network, public loadingCtrl: LoadingController, public toastCtrl: ToastController, public crudHttpProvider: CrudHttpProvider, public sqlite: SQLite, public viewCtrl: ViewController, public sim: Sim, public androidPermissions: AndroidPermissions) {
this.db_name = ConstantVariable.db_name;
this.myForm = this.formBuilder.group({
'mobile': ['', [Validators.required]],
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad LoginPage');
}
login() {
let post_data = { 'api_url': 'checkMobileNumber', "post": {'mobile': this.mobile} };
this.crudHttpProvider.callToCrudPost(post_data)
.then(data => {
let res = data;
if (res['status'] == 100) {
this.studname = res['data'].studname;
this.tuition_name = res['data'].tuition_name;
this.prn = res['data'].prn;
this.otp = res['data'].otp;
this.api_key = res['data'].api_key;
this.navCtrl.push('RegisterPage',{
"studname": this.studname,
"tuition_name": this.tuition_name,
"prn": this.prn,
"otp": this.otp,
"api_key": this.api_key
});
this.viewCtrl.dismiss();
this.checkPermission();
}
});
}
checkPermission() {
this.androidPermissions.checkPermission
(this.androidPermissions.PERMISSION.READ_SMS).then(
success => {
//if permission granted
this.watchSMS();
},
err =>{
this.androidPermissions.requestPermission
(this.androidPermissions.PERMISSION.READ_SMS).
then(success=>{
this.watchSMS();
},
err=>{
alert("cancelled")
});
});
this.androidPermissions.requestPermissions
([this.androidPermissions.PERMISSION.READ_SMS]);
}
watchSMS() {
if(window.SMS) window.SMS.startWatch(function(){
console.log('Succeed to start watching SMS');
this.navCtrl.push('DashboardPage');
let toast = this.toastCtrl.create({
message: "Succeed to start watching SMS.",
duration: 4000
});
toast.present();
document.addEventListener('onSMSArrive', this.smsArived);
}, function(){
console.log('failed to start watching SMS');
let toast = this.toastCtrl.create({
message: "failed to start watching SMS.",
duration: 4000
});
toast.present();
});
}
stopWatchSMS() {
if(window.SMS) window.SMS.stopWatch(function(){
console.log('Succeed to stop watching SMS');
}, function(){
console.log('failed to stop watching SMS');
});
}
smsArived = (result: any) => {
console.log("SMS DATA 2" + result);
let toast = this.toastCtrl.create({
message: "RESULT " + result,
duration: 4000
});
toast.present();
this.stopWatchSMS();
}
}
I implemented auto verify OTP via this tutorial. I had no trouble.
SMS is called inside of platform.ready() and it says : "Make sure always use method in Ionic Framework inside the platform.ready() else it will not work.". Finally, I think, you dont need to use window.
ionViewDidEnter()
{
this.platform.ready().then((readySource) => {
if(SMS) SMS.startWatch(()=>{
console.log('watching started');
}, Error=>{
console.log('failed to start watching');
});
document.addEventListener('onSMSArrive', (e:any)=>{
var sms = e.data;
console.log(sms);
});
});
}
working on an angular4 app that has 2 components/pages.
the first component is related to the object id:1 and it is one page and the second component is related to id:2 and it is another page. both of these pages share the same template 'page.component.html'
how do get the first component to only render the object with id:1? and the same for the second component. I understand that right now as it is set up, each component is going to both objects in the array.
is there a way i can do this in the service or each component?
data.json
[
{
"id": 1,
"array":
[
{
"name": "name1.a",
"title": "title1.a",
},
{
"name": "name1.b",
"title": "title1.b",
},
{
"name": "name1.c",
"title": "title1.c",
}
],
}
{
"id": 2,
"array":
[
{
"name": "name2",
"title": "title2",
}
]
}
]
page.component.html
<div *ngFor="let set of sets">
<p>{{set.name}}</p>
<p>{{set.title}}</p>
</div>
page.component.ts
// Imports
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { page } from '../page';
import { Observable } from 'rxjs/Rx';
// Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
#Injectable()
export class GenreService {
// Resolve HTTP using the constructor
constructor (private http: Http) {}
private pagesUrl = '../assets/json/data.json';
// Fetch all existing comments
getPages() : Observable<Page[]>{
// ...using get request
return this.http.get(this.pagesUrl)
// ...and calling .json() on the response to return data
.map((res:Response) => res.json())
//...errors if any
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
}
page.ts
export class Page {
constructor(
public id: number,
public array: array,
public name: string,
public title: string
){}
}
page.component.ts
import { Component, OnInit } from '#angular/core';
import { Page } from './page';
import { PageService } from '../../services/page.service';
#Component({
selector: 'page1',
templateUrl: './page.component.html',
providers: [ PageService ],
})
export class Page1Component implements OnInit {
pages: Page[];
errorMessage: string;
ngOnInit() {
this.getPages();
}
getPages() {
this.genreService.getPages()
.subscribe(
pages => this.pages = pages,
error => this.errorMessage = <any>error);
}
}
This will work good with you
<div *ngFor="let set of sets.array">
<p>{{set.name}}</p>
<p>{{set.title}}</p>
</div>
Maybe you can change the method getPages() for getPage(id: number) and filter by id. It would be like so:
getPage(id: number) : Observable<Page>{
// ...using get request
return this.http.get(this.pagesUrl)
// ...and calling .json() on the response to return data
.map((res:Response) => res.json())
// ... do antoher map an return the correct object
.map((data: Array<any>) => {
return data.find(x => x.id === id)
})
//...errors if any
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
With that fucntion it will only return the Page that you want,
Hope that helps.
While creating a modal in ionic 2 I am facing this error:
Error in ./QuizmePage class QuizmePage - caused by:
self.context.MyModal is not a function
can anyone please tell me how to overcome this error.
My code follows:
quiz.html page
<ion-content padding>
<button ion-button (click)="MyModal()">Share</button>
quiz.ts
import { Component } from '#angular/core';
import {ModalController, NavController, NavParams } from 'ionic-angular';
import { AccModal } from './modal'
#Component({
selector: 'page-quiz',
templateUrl: 'quiz.html'
})
export class QuizPage {
constructor(public navCtrl: NavController, public navParams: NavParams , public modalCtrl: ModalController ) {
}
MyModal() {
let myModal = this.modalCtrl.create(AccModal);
myModal.present();
}
}
modal.ts
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular/index';
#Component ({
template: `
<ion-card class='popover'>
<ion-card-content>
Hello
</ion-card-content>
</ion-card>
`
})
export class AccModal {
private dumbData: number;
constructor(private params: NavParams) {
this.dumbData= 22;
}
}
This is the first component where i am pushing those things into array named items and i am trying to get it in the second component through service
import { Component } from '#angular/core';
import { FormBuilder, FormControl } from '#angular/forms';
import {AppService} from '../second/app.service';
import { Router } from '#angular/router';
import { Http,Response } from '#angular/http';
import { routing, appRoutingProviders } from '../app.route';
import { Validators } from '#angular/forms';
import {BrowserModule} from '#angular/platform-browser';
#Component({
selector: 'first-app',
templateUrl:"../app/src/component/first/app.firstpage.html"
})
export class FirstComponent
{
data:any;
public items=[];
public edited=false;
public city=false;
public dateCon=false;
inputForm: FormGroup;
Select: FormControl;
Selectt: FormControl;
dat:FormControl;
constructor(private appservice:AppService,builder: FormBuilder, router:Router)
{
this.appservice.getData().subscribe(res=>{this.data=res.json()});
console.log(this.data);
this.Select = new FormControl('', [
Validators.required
]);
this.Selectt = new FormControl('', [
Validators.required
]);
this.dat = new FormControl('', [
Validators.required
]);
this.inputForm = builder.group({
Select: this.Select,
Selectt: this.Selectt,
dat: this.dat
});
this.router=router;
this.appservice=appservice;
}
ngOnInit(){
this.appservice.getData()
}
onclick(a,b) {
console.log(this.data);
let sel1=this.inputForm.value.Select;
let sel2=this.inputForm.value.Selectt;
let sel3=this.inputForm.value.dat;
console.log(sel3);
console.log(sel1);
console.log(sel2);
console.log(this.data.bus.length);
for(let i=0;i<this.data.bus.length;i++){
if((this.data.bus[i].from==sel1)&&(this.data.bus[i].to==sel2))
{
this.items.push(this.data.bus[i]);
}
}
this.appservice.setData(this.items);
}
if((sel1!="")&&(sel2!="")&&(sel3!="")&&(sel1!=sel2))
{
this.router.navigate(['/sec-component']);
}
else if((sel1=="")&&(sel2=="")&&(sel3==""))
{
this.edited=true;
}
if((sel1==sel2)&&((sel1!="")&&(sel2!="")))
{
this.edited=false;
this.city=true;
}
else
{
this.city=false;
}
if(sel1!=sel2)
{
this.edited=false;
}
if(sel3=="")
{
this.dateCon=true;
}
else
{
this.dateCon=false;
}
}
}
This is the second component to which i am passing this array and i need to get that printed over there and each properties to be accessed rather than the entire stuff.
import { Component } from '#angular/core';
import {AppService} from '../first/first.service';
#Component({
template:
`
<h1>second component</h1>
<h1>second component</h1>
<p >{{myName}}</p>
`
})
export class SecondComponent {
constructor(private appservice: AppService)
{
this.appservice=appservice;
this.myName=appservice.getVal();
}
}
This is the service page where i am returning the values
import {Component, Injectable,Input,Output,EventEmitter} from '#angular/core'
import { Http, Response } from '#angular/http';
export interface myData
{
name:any;
}
#Injectable()
export class AppService
{
sharingData: myData={name:""};
constructor(private http:Http){ }
getData()
{
return this.http.get('./app/src/component/busDet.json')
}
setData(i)
{
console.log('save data function called' + i + this.sharingData.name);
this.sharingData.name=i;
console.log(this.sharingData.name);
}
getVal()
{
console.log(this.sharingData.name);
return this.sharingData.name;
}
}
I am getting the output as object.object
I am not able to get the values with in the JSON in the next component.