How to call a function in app.component.ts menu before going a component to check connection exist?

Friends,
I need to go a Component in menu item if net connectivity is available. My sample menu item is

this.appMenuItems =
    [   {"title": "Home",  "titleM": "ഹോം", "component": HomePage,"icon": "home" },
        {"title": "Govt Orders","titleM": "സര്‍ക്കാര്‍ ഉത്തരവുകള്‍ ","component": GosearchPage, "icon": "search" },
];

I need to go Second item if net connectivity available. So I need to call a function and check it … If no connectivity show a message and else goto component.

How this check can done ?

Please advise

Thanks
Anes

Friends,

I tried like this

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', function: this.message() },

But in that when the page loads the function call occur. I need to call that when that particular menu click,

 message() {
  alert("jssjs");
  return false;

  }

please advise

ThNKs

Anes

basically @anes when app loads it load the app.component.ts then load the spacific pages which is set as root page. so function defined in app.component run first.
if we want to run that function which is in app.component.ts
after load the another page. then you have to use the events in you app
means when certain event fire. your subscrbing in app.component call then this function call your specific function
i do some similar work
you can check
it

app.component.ts

import {
Events,
Nav,
} from ‘ionic-angular’;

constructor( public events: Events ) {
events.subscribe( SETTINGS_CONSTANTS.EVENT_REQUEST_TIMEOUT, this.sessionLogout);
}

sessionLogout = () => {
//this.navCtrl.setRoot( SETTINGS_CONSTANTS.AUTHENTICATE_PAGE );
// do whatever you want
}

from interceptor.ts

import {
Events
} from ‘ionic-angular’;

constructor( public helperFunction: HelperFunctions, public events: Events ) {
this.events.publish( SETTINGS_CONSTANTS.EVENT_REQUEST_TIMEOUT);
}

1 Like

Hi, @anespa

You have to use ionic native network plugin for check network connectivity in app,

Add this code in app.component.ts. when a platform is ready,

import { ViewChild } from '@angular/core';
import { Nav } from 'ionic-angular';

@ViewChild(Nav) navCtrl: Nav;

let disconnectSub = Network.onDisconnect().subscribe(() => {
  console.log('you are offline');
  // For reload current active page
  this.navCtrl.setRoot(this.navCtrl.getActive().component);
});

let connectSub = Network.onConnect().subscribe(()=> {
  console.log('you are online');
  // For reload current active page
  this.navCtrl.setRoot(this.navCtrl.getActive().component);
});

Now, for performing offline or online operation in component file you need to add this code in each component file constructor,

if(Network.type == 'none'){
   // For offlien opration  
}else{
  // For online opration
}

Thank you.

I think use a service could be propper.

@anespa If you want that on the menu click, you should pass your function to the property, instead of calling it and return the result to the property.

Instead of:

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', function: this.message() },

(this.message() will be called when the object is created)

do this:

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', function: () => this.message() },

(this.message() will be called when function is called)

Also, try to avoid reserved words as property names (in this case, function) and use some other word (it may not cause a problem here, but could cause somewhere else). You could it change to, for example:

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', fn: () => this.message() },

And in your html you would call the click (or tap) like:

(click)="menuItem.fn()"

Dear Lucas ,

I tried as you suggest , but no expected alert occur…

my sample app.component.ts is

import { Component, ViewChild } from '@angular/core';

import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';

import { Storage } from '@ionic/storage';

import { AboutPage } from '../pages/about/about';
import { AccountPage } from '../pages/account/account';
import { LoginPage } from '../pages/login/login';
import { MapPage } from '../pages/map/map';
import { SignupPage } from '../pages/signup/signup';
import { TabsPage } from '../pages/tabs-page/tabs-page';
import { TutorialPage } from '../pages/tutorial/tutorial';
import { SchedulePage } from '../pages/schedule/schedule';
import { SpeakerListPage } from '../pages/speaker-list/speaker-list';
import { SupportPage } from '../pages/support/support';

import { ConferenceData } from '../providers/conference-data';
import { UserData } from '../providers/user-data';

export interface PageInterface {
  title: string;
  name: string;
  component: any;
  fn?: any;
  icon: string;
  logsOut?: boolean;
  index?: number;
  tabName?: string;
  tabComponent?: any;
}

@Component({
  templateUrl: 'app.template.html'
})
export class ConferenceApp {
  // the root nav is a child of the root app component
  // @ViewChild(Nav) gets a reference to the app's root nav
  @ViewChild(Nav) nav: Nav;

  // List of pages that can be navigated to from the left menu
  // the left menu only works after login
  // the login page disables the left menu
  appPages: PageInterface[] = [
    { title: 'Schedule', name: 'TabsPage', component: TabsPage, tabComponent: SchedulePage, index: 0, icon: 'calendar'},
    { title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', fn: () => this.message() },
    { title: 'Map', name: 'TabsPage', component: TabsPage, tabComponent: MapPage, index: 2, icon: 'map' },
    { title: 'About', name: 'TabsPage', component: TabsPage, tabComponent: AboutPage, index: 3, icon: 'information-circle' }
  ];
  loggedInPages: PageInterface[] = [
    { title: 'Account', name: 'AccountPage', component: AccountPage, icon: 'person' },
    { title: 'Support', name: 'SupportPage', component: SupportPage, icon: 'help' },
    { title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
  ];
  loggedOutPages: PageInterface[] = [
    { title: 'Login', name: 'LoginPage', component: LoginPage, icon: 'log-in' },
    { title: 'Support', name: 'SupportPage', component: SupportPage, icon: 'help' },
    { title: 'Signup', name: 'SignupPage', component: SignupPage, icon: 'person-add' }
  ];
  rootPage: any;

  constructor(
    public events: Events,
    public userData: UserData,
    public menu: MenuController,
    public platform: Platform,
    public confData: ConferenceData,
    public storage: Storage,
    public splashScreen: SplashScreen
  ) {

    // Check if the user has already seen the tutorial
    this.storage.get('hasSeenTutorial')
      .then((hasSeenTutorial) => {
        if (hasSeenTutorial) {
          this.rootPage = TabsPage;
        } else {
          this.rootPage = TutorialPage;
        }
        this.platformReady()
      });

    // load the conference data
    confData.load();

    // decide which menu items should be hidden by current login status stored in local storage
    this.userData.hasLoggedIn().then((hasLoggedIn) => {
      this.enableMenu(hasLoggedIn === true);
    });
    this.enableMenu(true);

    this.listenToLoginEvents();
  }

  message() {
  alert("jssjs");
  return false;

  }

  openPage(page: PageInterface) {
    let params = {};

    //alert("page is"+JSON.stringify(page.name));

    // the nav component was found using @ViewChild(Nav)
    // setRoot on the nav to remove previous pages and only have this page
    // we wouldn't want the back button to show in this scenario
    if (page.index) {
      params = { tabIndex: page.index };
    }

    // If we are already on tabs just change the selected tab
    // don't setRoot again, this maintains the history stack of the
    // tabs even if changing them from the menu
    if (this.nav.getActiveChildNavs().length && page.index != undefined) {
      this.nav.getActiveChildNavs()[0].select(page.index);
    } else {
      // Set the root of the nav with params if it's a tab index
      this.nav.setRoot(page.name, params).catch((err: any) => {
        console.log(`Didn't set nav root: ${err}`);
      });
    }

    if (page.logsOut === true) {
      // Give the menu time to close before changing to logged out
      this.userData.logout();
    }
  }

  openTutorial() {
    this.nav.setRoot(TutorialPage);
  }

  listenToLoginEvents() {
    this.events.subscribe('user:login', () => {
      this.enableMenu(true);
    });

    this.events.subscribe('user:signup', () => {
      this.enableMenu(true);
    });

    this.events.subscribe('user:logout', () => {
      this.enableMenu(false);
    });
  }

  enableMenu(loggedIn: boolean) {
    this.menu.enable(loggedIn, 'loggedInMenu');
    this.menu.enable(!loggedIn, 'loggedOutMenu');
  }

  platformReady() {
    // Call any initial plugins when ready
    this.platform.ready().then(() => {
      this.splashScreen.hide();
    });
  }

  isActive(page: PageInterface) {
    let childNav = this.nav.getActiveChildNavs()[0];

    // Tabs are a special case because they have their own navigation
    if (childNav) {
      if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
        return 'primary';
      }
      return;
    }

    if (this.nav.getActive() && this.nav.getActive().name === page.name) {
      return 'primary';
    }
    return;
  }
}

my template (app.template.html) is

<ion-split-pane>

  <!-- logged out menu -->
  <ion-menu id="loggedOutMenu" [content]="content">

    <ion-header>
      <ion-toolbar>
        <ion-title>Menu</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content class="outer-content">

      <ion-list>
        <ion-list-header>
          Navigate
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Account
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of loggedOutPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Tutorial
        </ion-list-header>
        <button ion-item menuClose (click)="openTutorial()">
          <ion-icon item-start name="hammer"></ion-icon>
          Show Tutorial
        </button>
      </ion-list>
    </ion-content>

  </ion-menu>

  <!-- logged in menu -->
  <ion-menu id="loggedInMenu" [content]="content">

    <ion-header>
      <ion-toolbar>
        <ion-title>Menu</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content class="outer-content">

      <ion-list>
        <ion-list-header>
          Navigate
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Account
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of loggedInPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Tutorial
        </ion-list-header>
        <button ion-item menuClose (click)="openTutorial()">
          <ion-icon item-start name="hammer"></ion-icon>
          Show Tutorial
        </button>
      </ion-list>

    </ion-content>

  </ion-menu>

  <!-- main navigation -->
  <ion-nav [root]="rootPage" #content swipeBackEnabled="false" main name="app"></ion-nav>

</ion-split-pane>

Please advise

Thanks

Anes

2 Likes

@anespa You haven’t posted your html.

Sorry I edit it please check and advise …

@anespa Well, you are not calling the function in your html. You could change:

(click)="openPage(p)"

to

(click)="p.fn ? p.fn() : openPage(p)"

(Will call the function if there is one, otherwise will call the open page. You need to open the page inside the fn (in your case, the method message()), otherwise the page won’t open if there is connection)

Alternative Solution

If the function is generic and you will handle it the same way for all pages that need internet connection, an even better way would be handling inside the open page (you don’t need to change the html):

openPage(page: PageInterface) {
	if (page.needConnection) {
		// verify the connection state and throw an error if it's not connected
		alert("jssjs");
		return false;
	}

	// the rest of the openPage() method...
}

The objects that you want to handle connection you would define the property needConnection with true (add the field to the interface):

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', needConnection: true },

(This is only in case you want to handle all cases the same way, otherwise change the HTML like I posted above and create a different function for each case)

Dear Lucas ,

I tried your first advise and change template as

<ion-split-pane>

  <!-- logged out menu -->
  <ion-menu id="loggedOutMenu" [content]="content">

    <ion-header>
      <ion-toolbar>
        <ion-title>Menu</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content class="outer-content">

      <ion-list>
        <ion-list-header>
          Navigate
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of appPages" (click)="p.fn ? p.fn() : openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Account
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of loggedOutPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Tutorial
        </ion-list-header>
        <button ion-item menuClose (click)="openTutorial()">
          <ion-icon item-start name="hammer"></ion-icon>
          Show Tutorial
        </button>
      </ion-list>
    </ion-content>

  </ion-menu>

  <!-- logged in menu -->
  <ion-menu id="loggedInMenu" [content]="content">

    <ion-header>
      <ion-toolbar>
        <ion-title>Menu</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content class="outer-content">

      <ion-list>
        <ion-list-header>
          Navigate
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Account
        </ion-list-header>
        <button ion-item menuClose *ngFor="let p of loggedInPages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{p.title}}
        </button>
      </ion-list>

      <ion-list>
        <ion-list-header>
          Tutorial
        </ion-list-header>
        <button ion-item menuClose (click)="openTutorial()">
          <ion-icon item-start name="hammer"></ion-icon>
          Show Tutorial
        </button>
      </ion-list>

    </ion-content>

  </ion-menu>

  <!-- main navigation -->
  <ion-nav [root]="rootPage" #content swipeBackEnabled="false" main name="app"></ion-nav>

</ion-split-pane>

and controller as (app.component.ts)

import { Component, ViewChild } from '@angular/core';

import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';

import { Storage } from '@ionic/storage';

import { AboutPage } from '../pages/about/about';
import { AccountPage } from '../pages/account/account';
import { LoginPage } from '../pages/login/login';
import { MapPage } from '../pages/map/map';
import { SignupPage } from '../pages/signup/signup';
import { TabsPage } from '../pages/tabs-page/tabs-page';
import { TutorialPage } from '../pages/tutorial/tutorial';
import { SchedulePage } from '../pages/schedule/schedule';
import { SpeakerListPage } from '../pages/speaker-list/speaker-list';
import { SupportPage } from '../pages/support/support';

import { ConferenceData } from '../providers/conference-data';
import { UserData } from '../providers/user-data';

export interface PageInterface {
  title: string;
  name: string;
  component: any;
  icon: string;
  logsOut?: boolean;
  fn?: any;
  index?: number;
  tabName?: string;
  tabComponent?: any;
}

@Component({
  templateUrl: 'app.template.html'
})
export class ConferenceApp {
  // the root nav is a child of the root app component
  // @ViewChild(Nav) gets a reference to the app's root nav
  @ViewChild(Nav) nav: Nav;

  // List of pages that can be navigated to from the left menu
  // the left menu only works after login
  // the login page disables the left menu
  appPages: PageInterface[] = [
    { title: 'Schedule', name: 'TabsPage', component: TabsPage, tabComponent: SchedulePage, index: 0, icon: 'calendar', fn: () => this.message()},
    { title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', fn: () => this.message() },
    { title: 'Map', name: 'TabsPage', component: TabsPage, tabComponent: MapPage, index: 2, icon: 'map' },
    { title: 'About', name: 'TabsPage', component: TabsPage, tabComponent: AboutPage, index: 3, icon: 'information-circle' }
  ];
  loggedInPages: PageInterface[] = [
    { title: 'Account', name: 'AccountPage', component: AccountPage, icon: 'person' },
    { title: 'Support', name: 'SupportPage', component: SupportPage, icon: 'help' },
    { title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
  ];
  loggedOutPages: PageInterface[] = [
    { title: 'Login', name: 'LoginPage', component: LoginPage, icon: 'log-in' },
    { title: 'Support', name: 'SupportPage', component: SupportPage, icon: 'help' },
    { title: 'Signup', name: 'SignupPage', component: SignupPage, icon: 'person-add' }
  ];
  rootPage: any;

  constructor(
    public events: Events,
    public userData: UserData,
    public menu: MenuController,
    public platform: Platform,
    public confData: ConferenceData,
    public storage: Storage,
    public splashScreen: SplashScreen
  ) {

    // Check if the user has already seen the tutorial
    this.storage.get('hasSeenTutorial')
      .then((hasSeenTutorial) => {
        if (hasSeenTutorial) {
          this.rootPage = TabsPage;
        } else {
          this.rootPage = TutorialPage;
        }
        this.platformReady()
      });

    // load the conference data
    confData.load();

    // decide which menu items should be hidden by current login status stored in local storage
    this.userData.hasLoggedIn().then((hasLoggedIn) => {
      this.enableMenu(hasLoggedIn === true);
    });
    this.enableMenu(true);

    this.listenToLoginEvents();
  }

 message() {
 alert("hi :");
 }

  openPage(page: PageInterface) {
    let params = {};

    // the nav component was found using @ViewChild(Nav)
    // setRoot on the nav to remove previous pages and only have this page
    // we wouldn't want the back button to show in this scenario
    if (page.index) {
      params = { tabIndex: page.index };
    }

    // If we are already on tabs just change the selected tab
    // don't setRoot again, this maintains the history stack of the
    // tabs even if changing them from the menu
    if (this.nav.getActiveChildNavs().length && page.index != undefined) {
      this.nav.getActiveChildNavs()[0].select(page.index);
    } else {
      // Set the root of the nav with params if it's a tab index
      this.nav.setRoot(page.name, params).catch((err: any) => {
        console.log(`Didn't set nav root: ${err}`);
      });
    }

    if (page.logsOut === true) {
      // Give the menu time to close before changing to logged out
      this.userData.logout();
    }
  }

  openTutorial() {
    this.nav.setRoot(TutorialPage);
  }

  listenToLoginEvents() {
    this.events.subscribe('user:login', () => {
      this.enableMenu(true);
    });

    this.events.subscribe('user:signup', () => {
      this.enableMenu(true);
    });

    this.events.subscribe('user:logout', () => {
      this.enableMenu(false);
    });
  }

  enableMenu(loggedIn: boolean) {
    this.menu.enable(loggedIn, 'loggedInMenu');
    this.menu.enable(!loggedIn, 'loggedOutMenu');
  }

  platformReady() {
    // Call any initial plugins when ready
    this.platform.ready().then(() => {
      this.splashScreen.hide();
    });
  }

  isActive(page: PageInterface) {
    let childNav = this.nav.getActiveChildNavs()[0];

    // Tabs are a special case because they have their own navigation
    if (childNav) {
      if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
        return 'primary';
      }
      return;
    }

    if (this.nav.getActive() && this.nav.getActive().name === page.name) {
      return 'primary';
    }
    return;
  }
}

But no alert happends… Why ?

Thanks

Anes

@anespa Make sure you click in one of the following items in your html:

{ title: 'Speakers', name: 'TabsPage', component: TabsPage, tabComponent: SpeakerListPage, index: 1, icon: 'contacts', fn: () => this.message() },

or

{ title: 'Schedule', name: 'TabsPage', component: TabsPage, tabComponent: SchedulePage, index: 0, icon: 'calendar', fn: () => this.message()},

(the ones with a function, their titles are Speakers and Schedule)

Also, see if the function is defined with the name fn.

It should work. If not, try to change (just for test purposes) the click to:

(click)="p.fn()"

See if it works and what is shown in the logs (if there is some errors).

@atif it works for me, thanks!