Data Storage Style Binding - ionic-framework

I have an ionic application with 2 pages. The information from one page (radio buttons) needs to update the text size of another page.
Am i correct in thinking the best way to go about this is to :
store the radio button value in local storage,
call the value in 2nd page from storage, and somehow use this value to update font size?
Any help appreciated.
i have watched tutorials online and this seems to be the only option.
I have the local storage part working correctly (suprisingly) but i am unsure how to update the font of a tag with this value.
Is a switch statement my next step ?

Pass the values as a Map from home page component
import { IonicPage, NavController, NavParams} from 'ionic-angular';
import {SecondaryPage} from '../../secondary-page/secondary-page';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class home{
styleSet:Map<string, string> = Map<string, string>();
constructor(public navCtrl: NavController, public navParams: NavParams){}
loadSecondaryPage(){
//Add data to the styleSet and pass from the navCtrl like below;
this.navCtrl.setRoot(SecondaryPage, this.styleSet);
}
}
Get this map from the second page and use it to load your styles
import { IonicPage, NavController, NavParams} from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-secondary',
templateUrl: 'secondary.html',
})
export class SecondaryPage{
constructor(public navCtrl: NavController, public navParams: NavParams){
  console.log(navParams.get('ItemNameOne')); //get those values by added key name in the map
console.log(navParams.get('ItemNameTwo'));
}
}
You can use any datatype as well to replace the map

Related

Ionic 3 NavController does not pop the view instead creates a new one

The ionViewDidLoad function seem to get called twice, which is causing multiple views being created of AddressPage. I have debugged this and it looks like whenever data is updated the new instance of view gets created. This behaviour seems to happen only when I use fireabse to save the address. If I comment out the code to save the address new view is not created and app navigates to previous screen.
Any way to avoid this?
I have tried ViewCotnroller.dismiss() and NavController.pop() inside saveAddress method but non seem to avoid creation of new view.
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar) {
platform.ready().then(() => {
statusBar.styleDefault();
statusBar.backgroundColorByHexString('#1572b5');
});
}
}
Home Page
import {NavController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider) {
}
//navigate to different view
navigate(){
this.navCtrl.push(AddressPage, {address:newAddress});
}
}
Address Page
import {NavController } from 'ionic-angular';
#Component({
selector: 'page-address',
templateUrl: 'address.html'
})
export class AddressPage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider, private navParams: NavParams) {
this.addressKey = this.navParams.get('key');
}
ionViewDidEnter(){
//load some data from server
}
saveAddress(){
//save data to server
this.firebaseProvider.saveAddress(newAddress);
//move back
this.navCtrl.pop();
}
}
Firebase provider that uses AngularFireDatabase
import { Injectable } from '#angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
#Injectable()
export class FirebaseProvider {
constructor(public afd: AngularFireDatabase) { }
saveAddress(address) {
this.afd.list('/addresses').push(address);
}
updateAddress(key,dataToUpdate){
return this.afd.list('addresses').update(key,dataToUpdate);
}
}
I have also tried this but it has the same issue.
this.firebaseProvider.saveAddress(newAddress).then(result => {
// loadingSpinner.dismiss();
this.navCtrl.pop();
});
this.firebaseProvider.updateAddress(this.addressKey, updateItems)
.then(() => {
// loadingSpinner.dismiss();
this.navCtrl.pop()
});
The HTML of save button
<button type="button" ion-button full color="primary-blue" (click)='saveAddress()'>Save</button>
Looks like unsubscribing to the subscribers fixes the issue. The HomePage view had subscribers which were not unsubscribed. I added the Observable Subscriptions into the array and unsubscribed as per code below.
ionViewWillLeave(){
this.subscriptions.forEach(item=>{
item.unsubscribe();
});
}
the push method returs a promise with the result of the action. I would change the save method like this:
saveAddress(address) {
return this.afd.list('/addresses').push(address);
}
Then in the controller I’d change it in this way:
saveAddress(){
//save data to serve
this.firebaseProvider.saveAddress(newAddress).then(result => {
//do yours validations
this.navCtrl.pop();
});
}
With thos you tide up the navigation of the page to the result of the Firebase execution. Give it a try to this approach and let me know if it didn’t work, anyway I would use oninit to load data only once as I guess you wanna do it rather than ionViewDidEnter.

Ionic spinner while Angularfire Firestore is loading

In an Ionic project i am using the code below to load a document collection from Firestore with the AngularFirestore wrappers.
Now that the content starts loading when the view was initialized i'm experiencing a delay by about 4-8 seconds until the firestore fetched data renders in my list-view, which is very very bad for the overall userexperience.
with the code below i'm able to show a loading spinner when the content starts loading bit i need it to stop showing the loader.
I have no clue how to trigger that event? Any help would be appreciated
thank you very much
import { City } from './../../model/City';
import { Component, AfterViewInit } from '#angular/core';
import { NavController, IonicPage, LoadingController } from 'ionic-angular';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage implements AfterViewInit {
citiesRef: AngularFirestoreCollection<City>
cities: Observable<City[]>;
loading = this.loadingCtrl.create({
content: 'Loading Regions...'
});
constructor(private loadingCtrl: LoadingController, private afs: AngularFirestore, public navCtrl: NavController) {
}
ngAfterViewInit(){
this.loading.present().then(()=>{
this.citiesRef = this.afs.collection<City>('regions', ref => ref.orderBy('name'));
this.cities = this.citiesRef.valueChanges();
})
}
}
Well, what I did was I subscribe to the this.cities. It worked in my case. The idea is it will fire loading.dismiss() once it is able to subscribe. Hope that helps
let loading = this.loadingCtrl.create({
content: 'Please wait...'
});
loading.present();
this.citiesRef=this.afs.collection('cities');
this.cities=this.citiesRef.valueChanges();
this.cities.subscribe(_=>{
loading.dismiss();
})

Ionic 3 - Set Root without tabs

How to do a navCtrl.setRoot(Page) without the tabs?
I foun a solution for Ionic2 but can't find it to the version 3.
this.navCtrl.setRoot(LoginPage);
import { NavController, App } from 'ionic-angular';
constructor(public app: App){}
// On your method, add code below
this.app.getRootNav().setRoot(SigninPage)
To show your page without tabs you need to get root of your navCtrl by using getRootNav() method.
import { NavController, App } from 'ionic-angular';
constructor(public navCtrl: NavController, public app: App){
}
any_method(){
this.app.getRootNav(Page);
}
More details of this can be read from this documentation: Navigating from an overlay component

force view to reload in ionic2 framework

After going through Clear History and Reload Page on Login/Logout Using Ionic Framework
I want to know same question, but for ionic2 using typescript.
On login and logout I need reload the app.ts, because there are classes that run libraries on construct.
it would be basically redirect to home and reload.
Found this answer here, (please note especially the line this.navCtrl.setRoot(this.navCtrl.getActive().component); which is by far the simplest solution that I've come across to reload present page for Ionic 2 & 3 and later versions of Angular (mine is 4), so credit due accordingly:
RELOAD CURRENT PAGE
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
refreshPage() {
this.navCtrl.setRoot(this.navCtrl.getActive().component);
}
}
If you want to RELOAD A DIFFERENT PAGE please use the following (note this.navCtrl.setRoot(HomePage);:
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
import { HomePage } from'../home/home';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
directToNewPage() {
this.navCtrl.setRoot(HomePage);
}
}
Ionic 1
I haven't used Ionic 2 but currently i m using Ionic 1.2 and if they are still using ui-router than you can use reload: true in ui-sref
or you can add below code to your logout controller
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
Angular 2
Use
$window.location.reload();
or
location.reload();
You have to implement the CanReuse interface, and override the routerCanReuse to return false. Then, try calling router.renavigate().
Your component should look like this:
class MyComponent implements CanReuse {
// your code here...
routerCanReuse(next: ComponentInstruction, prev: ComponentInstruction) {
return false;
}
}
And then, when you perform login/logout, call:
// navigate to home
router.renavigate()
This is a hack, but it works.
Wrap the logic that follows your template adjustment in a setTimeout and that gives the browser a moment to do the refresh:
/* my code which adjusts the ng 2 html template in some way */
setTimeout(function() {
/* processing which follows the template change */
}, 100);
For ionic 2 it works for me when you force page reload by triggering fireWillEnter on a view controller
viewController.fireWillEnter();
Here is what worked for me to refresh only current page-
I am trying to call refreshMe function when I call onDelete from my view page,
See how my page.ts file looks-
export class MyPage {
lines of code goes here like
public arr1: any;
public arr2: any;
public constructor(private nav: NavController, navParams: NavParams) {
this.nav = nav;
this.arr1 = [];
this.arr2 = [];
// console.log("hey array");
}
onDelete() {
perform this set of tasks...
...
...
refreshMe()
}
refreshMe() {
this.nav.setRoot(MyPage);
}
}
This is just refreshing only current page.
We can also call this function from view if we need as--
<ion-col width-60 offset-30 (click)="refreshMe()">
....
....
</ion-col>
I personally use these three lines to totally refresh a component
let active = this.navCtrl.getActive(); // or getByIndex(int) if you know it
this.navCtrl.remove(active.index);
this.navCtrl.push(active.component);
You can use the ionViewWillLeave() to display your splashscreen while component is reloading and then hide it with ionViewDidEnter() once its loaded.
Hope it helps

Ionic 2 passing tabs NavParams to tab

I'm starting out on creating my first app using Ionic 2 and through a lot of trial and error have got to a point where no number of Google searching can find anything to help.
I'm trying to pass some NavParams to a tab. The NavParams are available in the parent tabs page:
#Page({
templateUrl: 'build/pages/tabs/tabs.html'
})
export class TabsPage {
constructor(params: NavParams) {
this.params = params;
console.log(this.params); // returns NavParams {data: Object}
// this tells the tabs component which Pages should be each tab's root Page
this.tab1Root = Tab1;
this.tab2Root = Tab2;
this.tab3Root = Tab3;
}
}
But I cannot seem to get the NavParams within a tab itself:
#Page({
templateUrl: 'build/pages/tab1/tab1.html'
})
export class Tab1 {
constructor(nav: NavController, params: NavParams, platform: Platform) {
this.nav = nav;
this.params = params;
this.platform = platform;
console.log(this.params); // returns NavParams {data: null}
}
}
I'm just not entirely sure how to pass the params from the tabs page to the tab itself or somehow request a param from the tab parent. I assume something like:
this.tab1Root = Tab1(this.params);
Any help would be greatly appreciated!
This question is a few weeks old so you may have already found the answer. This feature was added in February: https://github.com/driftyco/ionic/issues/5475.
Taking the code from your original tab page, let's say a parameter is passed to the "parent" tab page and we want to store it in a property called fooId (this could be an object, or just a simple integer or string value, whatever):
#Component({
templateUrl: 'tabs.html'
})
export class TabsPage {
constructor(params: NavParams) {
this.params = params;
console.log(this.params); // returns NavParams {data: Object}
this.fooId = this.params.data;
// this tells the tabs component which Pages should be each tab's root Page
this.tab1Root = Tab1;
this.tab2Root = Tab2;
this.tab3Root = Tab3;
}
}
Then in your tabs.html, you can reference it like this using the rootParams attribute (rootParams is referenced in the documenation here):
<ion-tabs>
<ion-tab tabTitle="Tab1" [root]="tab1Root" [rootParams]="fooId"></ion-tab>
<ion-tab tabTitle="Tab2" [root]="tab2Root" [rootParams]="fooId"></ion-tab>
<ion-tab tabTitle="Tab3" [root]="tab3Root" [rootParams]="fooId"></ion-tab>
</ion-tabs>
Then in your Tab1 page, you can reference your NavParams just like any other page and the value passed for foodId will be there.
For those who haven't figured out yet .....
I've searched a lot and the only answer I got was using native storage or using a service or session storage...but that wasn't what I wanted ...
So, If you have data in NavParams in Tabs.ts page and want to it pass as [rootParam] to respective Tabs...
then what you need to do is instead of assigning NavParams to a variable in Tabs.ts page what you can do is bind it directly to the [rootParams] in the HTML page.
Like ..
tabs.ts
constructor(public navParams: NavParams) { }
tabs.html
<ion-tab [root]="tab1Root" [rootParams]="navParams.get('single')" tabTitle="Customer"></ion-tab>
<ion-tab [root]="tab2Root" [rootParams]="navParams.get('second')" tabTitle="Map"></ion-tab>
Or
tabs.html
<ion-tab [root]="tab1Root" [rootParams]="navParams.data" tabTitle="Customer"></ion-tab>
tab1.ts
constructor( public navParams: NavParams) {}
ionViewDidLoad() {
console.log('ionViewDidLoad tab1Page');
console.log(this.navParams.data);
}
There is no direct way to pass Params in Tab-Pages that I know of.
I think you could play around with the NavController to make it work.
A neat workaround is to put the parameter into an injected service:
app/services/params.js:
import {Injectable} from 'angular2/core';
#Injectable()
export class Params{
constructor(){
console.log("Params()");
this.params={};
}
}
and in the controller:
import {Params} from '../../services/params'
#Page({
templateUrl: 'build/pages/home/home.html',
})
export class XYPage{
constructor(nav: NavController,platform: Platform, params: Params) {
console.log("XYPage()",this);
console.log("XYPage()", params.params);
params.params={id="001"};
dont forget to inject the service in your #App
I tried with many methods but none of them were helpful to me. As my application did not involve much of complexities, I implemented it using ionic native storage plugin. In the event that triggers the new tab page, I will store some variable in native storage(snippet is as below).
this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
In the constructor or ionviewdidload page of the next tab page I will check for this variable and perform the required actions.Snippet is as below.
this.nativeStorage.getItem('myitem')
.then(
data => console.log(data),
error => console.error(error)
);
Note: This is suitable only for small application or where there is a requirement of passing limited set of variables. If there are lots of variable, it may take more space in the apps cache which may reduce the app performance.
tabs.html - add [rootParams]="paramName"; to the tab you want to pass data to
<ion-tabs>
<ion-tab tabTitle="Tab1" [root]="tab1Root" [rootParams]="fooId"></ion-tab>
<ion-tab tabTitle="Tab2" [root]="tab2Root"></ion-tab>
<ion-tab tabTitle="Tab3" [root]="tab3Root"></ion-tab>
</ion-tabs>
tabs.ts - set the key and data
export class TabsPage {
this.tab1Root = Tab1;
this.tab2Root = Tab2;
this.tab3Root = Tab3;
fooId: {
firstName: "lawlesscreation",
email: "user#email.com",
score: number // can also set it later in the constructor
}
constructor() {
let score = getScore(); //some method to get score
this.fooId.score = score;
}
}
tab1 page - import NavParams and use this.navParams.get(key) to get data
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-profile',
templateUrl: 'profile.html',
})
export class Tab1 {
firstName = this.navParams.get('firstName');
score = this.navParams.get('score');
userEmail = this.navParams.get('email');
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
}