Ionic2 navController pop with params (CallBack) - callback

I want to make a callback between two page.
In the page 1, i have this code:
DataInfo= [
{
Price: 0,
ClosePrice: 0,
UpdateTime:"",
DefaultPrice:0
}
]
GetClosePrice(i):number{
return DataInfo[i].ClosePrice;
}
i want to get the value of 'i' from the page 2, How can i load the function GetClosePrice() when the navcontroller return to the page 1 (this.navCtrl.pop())

SOURCE PAGE CLASS
this.navCtrl.push(Page,
{
data: this.data,
callback: this.getData
});
getData = data =>
{
return new Promise((resolve, reject) => {
for (let order of orders) {
this.data = data;
}
resolve();
});
};
TARGET PAGE CLASS
constructor(public navCtrl: NavController, public navParams: NavParams)
{
this.callback = this.navParams.get('callback');
this.data = this.navParams.get('data') || [];
}
sendData(event: any): void
{
this.callback(this.data).then( () => { this.navCtrl.pop() });
}
TARGET PAGE TEMPLATE
<button ion-button (click)="sendData($event)">

I answered similar question in Ionic forum. I just used Events listeners to achieve this behaviour.
MainPage-
import { NavController, Events } from 'ionic-angular';
import { OtherPage } from '../other/other';
export class MainPage{
constructor(private navCtrl: NavController,
private events: Events) { }
private pushOtherPage(){
this.events.subscribe('custom-user-events', (paramsVar) => {
// Do stuff with "paramsVar"
this.events.unsubscribe('custom-user-events'); // unsubscribe this event
})
this.navCtrl.push(OtherPage); // Push your "OtherPage"
}
}
OtherPage-
export class OtherPage {
// Under some function
this.navCtrl.pop().then(() => {
// Trigger custom event and pass data to be send back
this.events.publish('custom-user-events', myCustomParams);
});
}

Try this one - ionic2 pop with params

Related

Ionic 4 Pass parameter to another page

Please help how to pass param to another page in ionc 4?
As the push and navparam function seen not working anymore in ionic4.
https://medium.com/#muthudevendra/ionic-sharing-data-between-pages-8d0412cb8f58
Page1.ts
public country: string;
public email: string;
public password: string;
constructor(public nav: NavController) {}
goToAboutPage() {
let params: any = {
country: this.country,
email: this.email,
password: this.password
}
this.nav.navigateForward('/identity', { state: params }); // params to pass object/array
}
Page2.ts
constructor(public router: Router){
if (router.getCurrentNavigation().extras.state) {
const params = this.router.getCurrentNavigation().extras.state;
console.log(params.email)
console.log(params.password)
console.log(params.country)
}
}
in page.html use like this:
<ion-button routerLink="/yourAddress" [queryParams]="{ paramName : 'paramValue' }" ></ion-button>
in page.ts use like this:
import { NavController } from '#ionic/angular';
constructor(public navCtrl: NavController) {
this.navCtrl.navigateForward('/yourAddress?paramName=' + this.paramValue);
}
Read up on Activated route and NavigationExtras,
on page.ts have a function probably binded to a click event
goToNextpage() {
let navigationExtras : NavigationExtras = { state: { dataToBePassed:this.param }};
this.router.navigate(['/nextpage'], navigationExtras);
}
on nextpage.ts
import { ActivatedRoute, Router } from '#angular/router';
and do your dependency injection in the constructor like
constructor(
private route: ActivatedRoute,
private router: Router,
) {
this.route.queryParams.subscribe(params => {
if (this.router.getCurrentNavigation().extras.state) {
this.var = this.router.getCurrentNavigation().extras.state.dataToBePassed;
}
console.log(this.var); // will get you the data passed with key dataToBePassed
});
}

Cannot use namespace 'NavController'',NgZone',Google,as a type

I am new to ionic app developer, and I am facing this issue: when I open one Component, it is showing error messages, i.e, cannot use namespace as type ionic(NgZone,NavController and googlePlus). Why am I getting this error message?
Here is my code:
export class HomePage {
userProfile: any = null;
zone: NgZone;
constructor(public navCtrl: NavController, private googlePlus: GooglePlus) {
this.zone = new NgZone({});
firebase.auth().onAuthStateChanged( user => {
this.zone.run( () => {
if (user){
this.userProfile = user;
} else {
this.userProfile = null;
}
});
});
}
}
Maybe you forgot to update your project's package. Please try with:
npm install / npm update
Try the Below code : ( The NgZone object can be created as below )
export class HomePage {
userProfile: any = null;
zone: NgZone;
constructor(public navCtrl: NavController, private googlePlus: GooglePlus, private ngZone: NgZone) {
this.zone = ngZone;
firebase.auth().onAuthStateChanged( user => {
this.zone.run( () => {
if (user){
this.userProfile = user;
} else {
this.userProfile = null;
}
});
});
}
}

Events in Ionic v4

I'm using Ioni v4Beta and I'm traying to update the sidemenu when the user is login.
I search but the usual solution is use Events:
Ionic 3 refresh side menu after login
https://ionicframework.com/docs/api/util/Events/
But in the new version I don't find it, and I don't know how to do it
https://beta.ionicframework.com/docs/api
Thanks a lot, but I finally find how to import it:
import { Events } from '#ionic/angular';
Example on how to do it with subjects:
export const someEvent:Subject = new Subject();
export class ReceivingClass implements OnDestroy, OnInit
{
private someEventSubscription:Subscription;
public OnInit():void{
someEventSubscription = someEvent.subscribe((data) => console.log(data);
}
public onDestroy():void{
someEvent.unsubscribe();
}
}
export class SendingClass implements OnInit
{
public OnInit():void{
setTimeout(() => {
someEvent.next('hi');
}, 500);
}
}
Are you aware that Ionic v4 events will be deprecated soon?
I was also trying to update the sidemenu when a user logs in as well, so i tried using: import { Events } from '#ionic/angular';
However I got a warning referring me to this link https://angular.io/guide/observables#basic-usage-and-terms which I failed to follow because am not that familiar with observables.
After much research I found that I can still use events but I had to import them from angular's router directive.
This was my code before:
/* import was */
import { Events } from '#ionic/angular';
import { Storage } from '#ionic/storage';//ignore this import if doesn't apply to your code
/* inside the class */
constructor(
private events: Events,
private storage: Storage
) {
this.events.subscribe("updateMenu", () => {
this.storage.ready().then(() => {
this.storage.get("userLoginInfo").then((userData) => {
if (userData != null) {
console.log("User logged in.");
let user = userData.user;
console.log(user);
}
else {
console.log("No user found.");
let user = {};
}
}).catch((error)=>{
console.log(error);
});
}).catch((error)=>{
console.log(error);
});
});
}
changes i made that actually got my code working and deprecation warning gone:
/* import is now */
import { Router,RouterEvent } from '#angular/router';
import { Storage } from '#ionic/storage';//ignore this import if it does't apply to your code
Rest of code
constructor(
public router: Router,
public storage: Storage
){
this.router.events.subscribe((event: RouterEvent) => {
this.storage.ready().then(() => {
this.storage.get("userLoginInfo").then((userData) => {
if (userData != null) {
/*console.log("User logged in.");*/
let user = userData.user;
/*console.log(this.user);*/
}
else {
/*console.log("No user found.");*/
let user = {};
}
}).catch((error)=>{
console.log(error);
});
}).catch((error)=>{
console.log(error);
});
});
}
I got the idea after seeing this https://meumobi.github.io/ionic/2018/11/13/side-menu-tabs-login-page-ionic4.html. I hope my answer can be useful.
Steps to resolve the issue
import events in login page and in sidemenu view
In login page, after login success do your logic to publish the events.
for eg:
this.authService.doLogin(payload).subscribe((response) => {
if (response.status) {
this.storage.set('IS_LOGGED_IN', true);
this.events.publish('user:login');
}
}, (error) => {
console.log(error);
});
In sidemenu view, create a listener to watch the events 'user:login'
for eg:
this.menus = [];
// subscribe events
this.events.subscribe('user:login', () => {
// DO YOUR LOGIC TO SET THE SIDE MENU
this.setSidemenu();
});
// check whether the user is logged in or not
checkIsUserloggedIn() {
let isLoggedIn = false;
if (this.storage.get('IS_LOGGED_IN') == '' ||
this.storage.get('IS_LOGGED_IN') == null ||
this.storage.get('IS_LOGGED_IN') == undefined) {
isLoggedIn = false;
} else {
isLoggedIn = true;
}
return isLoggedIn;
}
// to set your sidemenus
setSidemenu() {
let isUserLoggedIn = this.checkIsUserloggedIn();
if(isUserLoggedIn) {
this.menus = ['Home', 'Aboutus', 'Contactus', 'My Profile', 'Logout'];
} else {
this.menus = ['Login', 'Home', 'Aboutus', 'Contactus'];
}
}

IONIC 2 - Cannot retrieve array inside ionViewDidLoad()

I want to retrieve places coordinates from restApi and display them on the map.
I got error : Cannot read property 'length' of undefined
Please help me !
I want you to tell me how i can get my data in order to add multiple markers.
This is my portion of code
import { Component, ViewChild, ElementRef } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Geolocation } from '#ionic-native/geolocation';
import { RestProvider } from '../../providers/rest/rest';
declare var google;
#Component({
selector: 'page-localisation',
templateUrl: 'localisation.html',
})
export class LocalisationPage {
#ViewChild('map') mapElement: ElementRef;
map: any;
places: Array<any>;
errorMessage : string;
constructor(public navCtrl: NavController, public navParams: NavParams, public geolocation: Geolocation, public rest: RestProvider) {
}
ionViewDidLoad(){
this.loadMap();
this.getPlaces();
this.addPlacesToMap()
console.log("Length : " + this.places.length) ; //Error Cannot read property 'length' of undefined
}
getPlaces() {
this.rest.getPlaces().subscribe(
places => this.places = places,
error => this.errorMessage = <any>error
);
}
loadMap(){
let latLng = new google.maps.LatLng(-4.066548, 5.356315);
let mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
}
addPlacesToMap(){
//...
}
addInfoWindow(marker, content){
let infoWindow = new google.maps.InfoWindow({
});
content: content
google.maps.event.addListener(marker, 'click', () => {
infoWindow.open(this.map, marker);
});
}
}
ionViewDidLoad is launched before "this.rest.getPlaces().subscribe" is finished... So your variable "places" is NULL
Change getPlaces to a Promise
async getPlaces() {
places = await this.rest.getPlaces() ;
return places
}
Then in ionViewDidLoad
ionViewDidLoad(){
var that = this ;
this.loadMap();
this.getPlaces().then((places)=>{
that.places = places;
console.log("Length : " + that.places.length) ;
});
this.addPlacesToMap()
}

Ionic3 framework network.onConnect().subscribe not working?

I have created a little phone app with Ionic. I am trying to implement a bit logic where the component knows when its online or offline. To do so I am using the network plugin fom Ionic and it just does not work as expected.
instead of updating the
this.connected
value every time when I switch on / off the network, it will only do so if I switch it off / on AND do something like switching from landscape to portrait mode, or work on a different app for a while and come back to the app.
Really puzzled by that.
Here is the code:
import {Component} from '#angular/core';
import {NavController, NavParams, Platform} from 'ionic-angular';
import {GooglePlus} from '#ionic-native/google-plus';
import {SurveyService} from "./survey.service";
import {Survey} from "../../Declarations/Survey";
import {SurveyPage} from "../survey/survey";
import {Network} from "#ionic-native/network";
#Component({
selector: 'page-home',
templateUrl: 'home.html',
providers: [SurveyService, Network]
})
export class HomePage {
public surveys: Survey[] = [];
public connected;
public networkType;
constructor(public navCtrl: NavController,
private googlePlus: GooglePlus,
private surveyService: SurveyService,
public navParams: NavParams,
platform: Platform,
private network: Network) {
this.checkForNetwork();
this.surveyService.getAvailable().subscribe(surveys => {
this.checkForNetwork();
this.surveys = surveys;
})
}
login() {
this.googlePlus.login({
'webClientId': '632130231957-dmjd154jhq1eenimedri3m0de6sh7tln.apps.googleusercontent.com'
}).then((res) => {
console.log(res);
}, (err) => {
console.log(err);
});
}
logout() {
this.googlePlus.logout().then(() => {
console.log("logged out");
});
}
openSurvey = (survey: Survey) => {
this.navCtrl.push(SurveyPage, {
survey: survey
});
}
checkForNetwork = () => {
this.networkType= this.network.type;
this.network.onDisconnect().subscribe(() => {
this.connected = false;
this.network.type = null;
});
this.network.onConnect().subscribe(() => {
this.connected = 'network connected!';
setTimeout(() => {
if (this.network.type === 'wifi') {
this.connected = true;
}
}, 3000);
});
}
}
OK, I worked it out:
Turns out that ionic works perfectly fine, but I tried to change the view of my application depending on whether
this.connected
is true or false. I did not realize that I needed to tell Angular to refresh its view by using Application
applicationRef.tick();
in the right place. So basically, once the Ionic changes the value of this.connected you need to tell Angular about it, here is the corrected part of the code:
You need to inject ApplicationRef into the constructor
constructor(public navCtrl: NavController,
...
private appReference: ApplicationRef) {
...
checkForNetwork = () => {
this.networkType= this.network.type;
this.network.onDisconnect().subscribe(() => {
this.connected = false;
this.network.type = null;
this.appReference.tick();
});
this.network.onConnect().subscribe(() => {
this.connected = 'network connected!';
setTimeout(() => {
if (this.network.type === 'wifi') {
this.connected = true;
this.appReference.tick();
}
}, 3000);
});
}