ionic3 - Didn't set nav root: invalid link: FeedbackPage - ionic-framework

I want when I clicked feedback button can go feedback page, but after I set up all, after clicked still showing tabsPage.
app.component.ts
appPages: PageInterface[] = [
{ title: '新闻', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'SOS', name: 'TabsPage', component: TabsPage, index: 1, icon: 'call' },
{ title: '服务', name: 'TabsPage', component: TabsPage, index: 2, icon: 'people' },
{ title: '反馈', name: 'FeedbackPage', component: FeedbackPage, icon: 'contacts' }
];
loggedInPages: PageInterface[] = [
{ title: '新闻', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'SOS', name: 'TabsPage', component: TabsPage, index: 1, icon: 'call' },
{ title: '服务', name: 'TabsPage', component: TabsPage, index: 2, icon: 'people' },
{ title: '反馈', name: 'FeedbackPage', component: FeedbackPage, icon: 'contacts' },
{ title: '注销', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
];
The last one is the feedback button, when I click feedback button just back to tabsPage not go into feedback page.
UPDATE:
I am checking this code in app.components.ts
openPage(page: PageInterface) {
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
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();
}
}
Is it need to change params?
app.html
<ion-menu id="loggedOutMenu" [content]="content">
<ion-header>
<ion-toolbar color="danger">
<ion-title>菜单</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header>请登录</ion-list-header>
<button color="wechat" style="width:40%" ion-button clear (click)= "wechatLogin()">
<ion-icon name="minan-login-wechat"></ion-icon>
</button>
<button color="facebook" style="width:40%" ion-button clear (click)= "FBLogin()">
<ion-icon name="minan-login-facebook"></ion-icon>
</button>
<ion-list-header>导航栏</ion-list-header>
<button menuClose ion-item *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-content>
</ion-menu>

Feedback page doesn't have own module because I am using 'ionic generate page Feedback --no-module' to generate my Feedback page
This means you are not using lazy loading and the page is not an IonicPage.
#IonicPage()
which sets the name property as the component name by default.
This will automatically create a link to the MyPage component using the same name as the class, name: 'MyPage'. The page can now be navigated to by using this name.
And also you dont have PageModule
In your case, you will have to set the imported component/page and not the string with your NavController functions.
Do:
this.nav.setRoot(page.component, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});//page.component

Based on your app structure, you app might be based on ionic conference starter template, what iv'e done is remove extra parameters in IonicModule.forRoot(ConferenceApp), like links array and extra objects, then do the lazy loading for your pages by Adding and importing an #IonicPage() on your components.
Before:
IonicModule.forRoot(ConferenceApp, {}, {
links: [
{ component: TabsPage, name: 'TabsPage', segment: 'tabs-page' },
{ component: SchedulePage, name: 'Schedule', segment: 'schedule' },
{ component: SessionDetailPage, name: 'SessionDetail', segment: 'sessionDetail/:sessionId' },
{ component: ScheduleFilterPage, name: 'ScheduleFilter', segment: 'scheduleFilter' },
{ component: SpeakerListPage, name: 'SpeakerList', segment: 'speakerList' },
{ component: SpeakerDetailPage, name: 'SpeakerDetail', segment: 'speakerDetail/:speakerId' },
{ component: MapPage, name: 'Map', segment: 'map' },
{ component: AboutPage, name: 'About', segment: 'about' },
{ component: TutorialPage, name: 'Tutorial', segment: 'tutorial' },
{ component: SupportPage, name: 'SupportPage', segment: 'support' },
{ component: AccountPage, name: 'AccountPage', segment: 'account' },
{ component: SignupPage, name: 'SignupPage', segment: 'signup' }
]
After:
IonicModule.forRoot(ConferenceApp),
login.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { LoginPage } from './login';
#NgModule({
declarations: [
LoginPage,
],
imports: [
IonicPageModule.forChild(LoginPage),
],
})
export class RequestTrainingPageModule {}
login.ts
import { Component } from '#angular/core';
import { NgForm } from '#angular/forms';
import { IonicPage, NavController } from 'ionic-angular';
import { UserOptions } from '../../interfaces/user-options';
import { UserData } from '../../providers/user-data';
import { TabsPage } from '../tabs-page/tabs-page';
#IonicPage()
#Component({
selector: 'page-user',
templateUrl: 'login.html'
})
export class LoginPage {
login: UserOptions = { username: '', password: '' };
submitted = false;
constructor(public navCtrl: NavController, public userData: UserData) { }
onLogin(form: NgForm) {
this.submitted = true;
if (form.valid) {
this.userData.login(this.login.username);
this.navCtrl.push(TabsPage);
}
}
onSignup() {
this.navCtrl.push('SignupPage');
}
}

Related

How to scroll to the bottom of the chat page in ionic 5

i am building a chatting mobile app with ionic 5, i want to be able to scroll to the bottom of the chat but its not working, i searched online but the solution i saw wasn't working, it just scrolled a little bit, but not to the end of the chat
Here is my code for the chat.page.html
<ion-header>
....
</ion-header>
<ion-content class="bg">
<ion-button expand="block" (click)="scrollContent()">Scroll 1</ion-button>
<div class="chat-container">
<div *ngFor="let message of messages; let i=index;" class="chat-bubble" [(ngClass)]="message.type">
<h6>{{ message.text }}</h6>
<p>{{ message.created }}</p>
</div>
</div>
</ion-content>
<ion-footer>
.......
</ion-footer>
Here's the code for the chat.page.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { IonContent } from '#ionic/angular';
#Component({
selector: 'app-chats',
templateUrl: './chats.page.html',
styleUrls: ['./chats.page.scss'],
})
export class ChatsPage implements OnInit {
messages=new Array()
#ViewChild(IonContent, { static: false }) content: IonContent;
constructor(
) { }
ngOnInit() {
this.messages=[
{ text: "Hey what's up?", type: 'received', created: '14:02' },
{ text: "Nothing", type: 'send', created: '14:05' },
{ text: "Want to go to the movies?", type: 'send', created: '14:05' },
{ text: "I'm sorry, I can't", type: 'received', created: '14:15' },
{ text: "but can we go tomorrow?", type: 'received', created: '14:16' },
{ text: "Nothing", type: 'send', created: '14:05' },
{ text: "Nothing", type: 'send', created: '14:05' },
{ text: "Nothing", type: 'send', created: '14:05' },
{ text: "Nothing", type: 'send', created: '14:05' },
{ text: "I'm sorry, I can't", type: 'received', created: '14:15' },
{ text: "but can we go tomorrow?", type: 'received', created: '14:16' },
]
}
scrollContent() {
this.content.scrollToBottom(300)
}
}
I want it to scroll to the bottom of the div with class="chat-container" when i click the button.
Please what am i doing thats not right
try this
scrollToBottomSetTimeOut(){
setTimeout(() => {
this.content.scrollToBottom();
}, 30);
}

Ionic 4 Manual Override of ion-select

Hi I need 'select from list' functionality on a form but with the ability to enter a value manually if needed.  I've been trying ion-select but there doesn't seem to be a way to have a manual override.  Is there a way to do this?
Thanks
For example
<ion-header>
<ion-toolbar>
<ion-title>kitlist testy</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<form [formGroup]="myForm">
<ion-list>
<ion-item>
<ion-label stacked>Lens</ion-label>
<ion-select placeholder="Select One">
<ion-select-option value="f">Female</ion-select-option>
<ion-select-option value="m">Male</ion-select-option>
</ion-select>
<ion-input type="text" formControlName='lens'></ion-input>
</ion-item>
</ion-list>
</form>
</ion-content>
will give
I want the user to be able to add their own value - which I will then store.
Thanks
Following Sergey's very helpful answer I have tried getting this to work and I'm stuck at inputAlert.onDidDismiss which gives me
Expected 0 arguments, but got 1
Here's the code which I have adjusted for my use case:-
import { Component, OnInit } from "#angular/core";
import { FormBuilder, FormGroup } from "#angular/forms";
import { AlertController } from "#ionic/angular";
#Component({
selector: "app-kitlist",
templateUrl: "./kitlist.page.html",
styleUrls: ["./kitlist.page.scss"]
})
export class KitlistPage implements OnInit {
kitlist = ["lens1", "lens2", "Custom"];
currentLens: any;
myForm: FormGroup;
constructor(
private fb: FormBuilder,
private alertController: AlertController
) {
this.myForm = new FormGroup({});
}
ngOnInit() {
this.myForm = this.fb.group({
lens: ""
});
this.myForm.valueChanges.subscribe(console.log);
}
submitForm() {
console.log("submit");
}
selectChanged(selectedLens) {
if (selectedLens === "Custom") {
this.inputCustomLensValue();
} else {
this.currentLens = selectedLens;
}
}
async inputCustomLensValue() {
const inputAlert = await this.alertController.create({
header: "Enter your custom lens:",
inputs: [{ type: "text", placeholder: "type in" }],
buttons: [{ text: "Cancel" }, { text: "Ok" }]
});
inputAlert.onDidDismiss(data => {
let customLensName: string = data.data.values[0];
if (customLensName) {
let indexFound = this.kitlist.findIndex(
lens => lens === customLensName
);
if (indexFound === -1) {
this.kitlist.push(customLensName);
this.currentLens = customLensName;
} else {
this.currentLens = this.kit[indexFound];
}
}
});
await inputAlert.present();
}
}
Since ion-select under the hood uses alert controller, I would leverage it directly and I would have a couple of alerts working together here:
In your template:
<ion-item>
<ion-label>Hair Color</ion-label>
<ion-button slot="end" (click)="selectColors()">{{ currentOptionLabel }}
<ion-icon slot="end" name="arrow-dropdown"></ion-icon>
</ion-button>
</ion-item>
You can style ion-button according to your needs.
Now in your ts file we can import Alert Controller and have 2 of them: one for selecting premade options and one that we will create input type of alert in case our user wants to add custom value.
I am not using button's handler's methods here to make sure Angular can pick up all the data changes:
import { Component } from '#angular/core';
import { AlertController } from '#ionic/angular';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.css'],
})
export class HomePage {
public colorOptions: Array<{type: string, label: string, value: string}>
public currentColorOptionIndex: number;
public currentOptionLabel: string;
constructor(public alertController: AlertController) {
this.currentColorOptionIndex = 1;
this.colorOptions = [
{
type: "radio",
label: "Custom",
value: "Custom"
},
{
type: "radio",
label: "Brown",
value: "Brown",
},
{
type: "radio",
label: "Dark",
value: "Dark",
}
]
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
}
async selectColors() {
const radioAlert = await this.alertController.create({
header: 'Prompt!',
inputs: this.colorOptions as any,
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary'
}, {
text: 'Ok'
}
]
});
await radioAlert.present();
radioAlert.onDidDismiss().then((data) => {
let selectedValue = data.data.values;
if (selectedValue === 'Custom') {
this.inputCustomColorValue()
};
this.currentColorOptionIndex = this.colorOptions.findIndex(option => option.value == selectedValue)
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
})
}
async inputCustomColorValue() {
const inputAlert = await this.alertController.create({
header: 'Enter your custom color:',
inputs: [
{
type: 'text',
placeholder: 'type in'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary'
}, {
text: 'Ok',
}
]
});
await inputAlert.present();
inputAlert.onDidDismiss().then((data) => {
let customValue = data.data.values[0];
let indexFound = this.colorOptions.findIndex(option => option.value == customValue)
if (indexFound !== -1) {
this.currentColorOptionIndex = indexFound
} else {
this.colorOptions.push(
{
type: 'radio',
label: customValue,
value: customValue,
}
)
this.currentColorOptionIndex = this.colorOptions.length - 1;
};
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
})
}
}
Updated: added the fact that now in latest Ionic versions (compared to Stackblitz that uses old 4 beta) onDidDismiss hook returns Promise and requires onDidDismiss.then((data) => {}) syntax vs onDidDismiss((data => {})

Meta tags not display on page view source using angular 6.1

I'm using Angular, I want to add meta tags dynamically.
I am using form : https://www.npmjs.com/package/#ngx-meta/core
npm install #ngx-meta/core --save
I Tried the code below, it is showing in inspect element (console), but it is not showing on source code:
import { NgModule } from '#angular/core';
import { MetaGuard } from '#ngx-meta/core';
import { MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning } from '#ngx-meta/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ChildrouterComponent } from './about/childrouter/childrouter.component';
const routes: Routes = [
{
path: '',
canActivateChild: [MetaGuard],
children: [
{
path: 'home',
component: HomeComponent,
data: {
meta: {
title: 'home home',
keywords: 'home,home,home,home,home',
description: 'Home, home sweet home... and what?',
'og:image': 'https://upload.wikimedia.org/wikipedia/commons/f/f8/superraton.jpg',
'og:type': 'website',
'og:locale': 'en_US',
'og:locale:alternate': 'en_US,nl_NL,tr_TR'
}
}
},
{
path: 'about',
component: AboutComponent,
data: {
meta: {
title: 'about hello',
keywords: 'about,about,about,about,about,about,about',
description: 'Have you seen my rubber hello?',
'og:image': 'https://upload.wikimedia.org/wikipedia/commons/f/f8/superraton.jpg',
'og:type': 'website',
'og:locale': 'en_US',
'og:locale:alternate': 'en_US,nl_NL,tr_TR'
}
}
},
{
path: 'dashboard',
component: DashboardComponent,
data: {
meta: {
title: 'dashboard hello',
keywords: 'dashboard,dashboard,dashboard,dashboard,dashboard,dashboard,dashboard',
description: 'Have you seen my dashboard hello?',
'og:image': 'https://upload.wikimedia.org/wikipedia/commons/f/f8/superraton.jpg',
'og:type': 'website',
'og:locale': 'en_US',
'og:locale:alternate': 'en_US,nl_NL,tr_TR'
}
}
}
]
}
]
#NgModule({
imports: [RouterModule.forRoot(routes),
MetaModule.forRoot()
],
exports: [RouterModule]
})
export class AppRoutingModule { }
It's working fine in inspect element but not showing any meta tags in page view source .

ionic3 - Can't resolve all parameters for UserDataProvider: ([object Object], [object Object], ?)

This is Ionic3 project and I was doing login page.
This page I want to show login button first in slide menu, after I login into apps, hidden login button and showing logout button. But when I was doing it this error coming out:
Can't resolve all parameters for UserDataProvider: ([object Object],
[object Object], ?).
This is my ionic info:
Ionic Framework: 3.6.0
Ionic Native: 2.4.1
Ionic App Scripts: 2.1.3
Angular Core: 4.0.0
Angular Compiler CLI: 4.0.0
Node: 6.11.3
OS Platform: macOS Sierra
Navigator Platform: MacIntel
User Agent: Mozilla/5.0 (Macintosh; Intel
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { QQSDK, QQShareOptions } from '#ionic-native/qqsdk';
import { Facebook, FacebookLoginResponse } from '#ionic-native/facebook';
import { TabsPage } from '../pages/tabs/tabs';
declare var Wechat:any;
export interface PageInterface {
title: string;
name: string;
component: any;
icon: string;
logsOut?: boolean;
index?: number;
tabName?: string;
tabComponent?: any;
}
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
appPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' }
];
loggedInPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
];
userData = null;
rootPage = TabsPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public events: Events, public menu: MenuController,
private qq: QQSDK,private fb: Facebook) {
this.initializeApp();
this.userData.hasLoggedIn().then((hasLoggedIn) => {
this.enableMenu(hasLoggedIn === true);
});
this.enableMenu(true);
this.listenToLoginEvents();
}
openPage(page: PageInterface) {
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
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();
}
}
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');
}
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;
}
initializeApp() {
this.platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
QQLogin(){
const loginOptions: QQShareOptions = {
client: this.qq.ClientType.QQ,
};
this.qq.ssoLogin(loginOptions)
.then((result) => {
console.log('shareNews success');
alert('token is ' + result.access_token);
alert('userid is ' + result.userid);
})
.catch(error => {
console.log(error);
});
this.qq.logout().then(() => {
console.log('logout success');
}).catch(error => {
console.log(error);
});
}
wechatLogin(){
let scope = "snsapi_userinfo",
state = "_" + (+new Date());
Wechat.auth(scope, state, function (response) {
// you may use response.code to get the access token.
alert(JSON.stringify(response));
}, function (reason) {
alert("Failed: " + reason);
});
}
weiboLogin(){}
FBLogin(){
this.fb.login(['email', 'public_profile']).then((response: FacebookLoginResponse) => {
this.fb.api('me?fields=id,name,email,first_name,picture.width(360).height(360).as(picture_large)', []).then(profile => {
this.userData = {email: profile['email'], first_name: profile['first_name'], picture: profile['picture_large']['data']['url'], username: profile['name']}
});
});
}
}
EDIT:
app.html
<ion-menu id="loggedOutMenu" [content]="content">
<ion-header>
<ion-toolbar color="danger">
<ion-title>菜单</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header>请登录</ion-list-header>
<button style="width:40%" ion-button round outline (click)= "QQLogin()">
<ion-icon name="minan-qq"></ion-icon>
</button>
<button color="wechat" style="width:40%" ion-button round outline (click)= "wechatLogin()">
<ion-icon name="minan-wechat"></ion-icon>
</button>
<button color="danger" style="width:40%" ion-button round outline (click)= "weiboLogin()">
<ion-icon name="minan-weibo"></ion-icon>
</button>
<button color="facebook" style="width:40%" ion-button round outline (click)= "FBLogin()">
<ion-icon name="minan-facebook"></ion-icon>
</button>
</ion-list>
<ion-list>
<ion-list-header>导航栏1</ion-list-header>
<button menuClose ion-item *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-content>
</ion-menu>
<ion-menu id="loggedInMenu" [content]="content">
<ion-header>
<ion-toolbar color="danger">
<ion-title>菜单</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-card *ngIf="userData">
<ion-card-header>账号</ion-card-header>
<ion-thumbnail>
<img [src]="userData.picture" />
</ion-thumbnail>
<ion-card-title>{{ userData.username }}</ion-card-title>
<!-- <ion-card-content>
<p>Email: {{ userData.email }}</p>
<p>First Name: {{ userData.first_name }}</p>
</ion-card-content> -->
</ion-card>
<ion-list>
<ion-list-header>导航栏2</ion-list-header>
<button menuClose ion-item *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-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
UPDATE:
app.module.ts
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { QQSDK } from '#ionic-native/qqsdk';
import { Facebook } from '#ionic-native/facebook';
import { SocialSharing } from '#ionic-native/social-sharing';
import { PhotoViewer } from '#ionic-native/photo-viewer';
import { BrowserModule } from '#angular/platform-browser';
import { HttpModule } from '#angular/http';
import { OneSignal } from '#ionic-native/onesignal';
import { IonicStorageModule } from '#ionic/storage';
import { MyApp } from './app.component';
import { SosPage } from '../pages/sos/sos';
import { ServicesPage } from '../pages/services/services';
import { NewsPage } from '../pages/news/news';
import { NewsDetailPage } from '../pages/news-detail/news-detail';
import { ServicesDetailPage } from '../pages/services-detail/services-detail';
import { TabsPage } from '../pages/tabs/tabs';
import { InsurencePage } from '../pages/insurence/insurence';
import { InsurenceDetailPage } from '../pages/insurence-detail/insurence-detail';
import { EducationPage } from '../pages/education/education';
import { EducationDetailPage } from '../pages/education-detail/education-detail';
import { TravelPage } from '../pages/travel/travel';
import { TravelDetailPage } from '../pages/travel-detail/travel-detail';
import { InvestmentPage } from '../pages/investment/investment';
import { InvestmentDetailPage } from '../pages/investment-detail/investment-detail';
import { LifePage } from '../pages/life/life';
import { LifeDetailPage } from '../pages/life-detail/life-detail';
import { NewsDataProvider } from '../providers/news-data/news-data';
import { ServicesDataProvider } from '../providers/services-data/services-data';
import { UserDataProvider } from '../providers/user-data/user-data';
#NgModule({
declarations: [
MyApp,
SosPage,
ServicesPage,
NewsPage,
TabsPage,
NewsPage,
NewsDetailPage,
ServicesDetailPage,
InsurencePage,EducationPage,TravelPage,InvestmentPage,LifePage,
InsurenceDetailPage,TravelDetailPage,InvestmentDetailPage,EducationDetailPage,LifeDetailPage
],
imports: [
BrowserModule,
HttpModule,
IonicStorageModule.forRoot(),
IonicModule.forRoot(MyApp,{
})
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
SosPage,
ServicesPage,
NewsPage,
TabsPage,
NewsPage,
NewsDetailPage,
ServicesDetailPage,
InsurencePage,EducationPage,TravelPage,InvestmentPage,LifePage,
InsurenceDetailPage,TravelDetailPage,InvestmentDetailPage,EducationDetailPage,LifeDetailPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},
NewsDataProvider,
ServicesDataProvider,
SocialSharing,
PhotoViewer,
QQSDK,Facebook,
OneSignal,
UserDataProvider]
})
export class AppModule {}
user-data.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Events } from 'ionic-angular';
import 'rxjs/add/operator/map';
#Injectable()
export class UserDataProvider {
HAS_LOGGED_IN = 'hasLoggedIn';
constructor(public http: Http, public events: Events, public storage: Storage) {
console.log('Hello UserDataProvider Provider');
}
login(username: string): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUsername(username);
this.events.publish('user:login');
};
signup(username: string): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUsername(username);
this.events.publish('user:signup');
};
logout(): void {
this.storage.remove(this.HAS_LOGGED_IN);
this.storage.remove('username');
this.events.publish('user:logout');
};
setUsername(username: string): void {
this.storage.set('username', username);
};
getUsername(): Promise<string> {
return this.storage.get('username').then((value) => {
return value;
});
};
hasLoggedIn(): Promise<boolean> {
return this.storage.get(this.HAS_LOGGED_IN).then((value) => {
return value === true;
});
};
}
please update your code file as below
user-data.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Events } from 'ionic-angular';
import { Storage } from '#ionic/storage';
import 'rxjs/add/operator/map';
#Injectable()
export class UserDataProvider {
HAS_LOGGED_IN = 'hasLoggedIn';
constructor(public http: Http, public events: Events, public storage: Storage) {
console.log('Hello UserDataProvider Provider');
}
login(user: any): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUser(user);
this.events.publish('user:login');
};
signup(user: any): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUser(user);
this.events.publish('user:signup');
};
logout(): void {
this.storage.remove(this.HAS_LOGGED_IN);
this.storage.remove('username');
this.events.publish('user:logout');
};
setUser(user: any): void {
this.storage.set('user', user);
};
getUser(): Promise<any> {
return this.storage.get('user').then((value) => {
return value;
});
};
hasLoggedIn(): Promise<boolean> {
return this.storage.get(this.HAS_LOGGED_IN).then((value) => {
return value === true;
});
};
}
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { QQSDK, QQShareOptions } from '#ionic-native/qqsdk';
import { Facebook, FacebookLoginResponse } from '#ionic-native/facebook';
import { UserDataProvider } from '../src/to/user-data'
import { TabsPage } from '../pages/tabs/tabs';
declare var Wechat:any;
export interface PageInterface {
title: string;
name: string;
component: any;
icon: string;
logsOut?: boolean;
index?: number;
tabName?: string;
tabComponent?: any;
}
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
appPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' }
];
loggedInPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
];
//userData = null;
rootPage = TabsPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public events: Events, public menu: MenuController,
private qq: QQSDK,private fb: Facebook, private userData: UserDataProvider) {
this.initializeApp();
this.userData.hasLoggedIn().then((hasLoggedIn) => {
this.enableMenu(hasLoggedIn === true);
});
this.enableMenu(true);
this.listenToLoginEvents();
}
openPage(page: PageInterface) {
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
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();
}
}
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');
}
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;
}
initializeApp() {
this.platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
QQLogin(){
const loginOptions: QQShareOptions = {
client: this.qq.ClientType.QQ,
};
this.qq.ssoLogin(loginOptions)
.then((result) => {
console.log('shareNews success');
alert('token is ' + result.access_token);
alert('userid is ' + result.userid);
})
.catch(error => {
console.log(error);
});
this.qq.logout().then(() => {
console.log('logout success');
}).catch(error => {
console.log(error);
});
}
wechatLogin(){
let scope = "snsapi_userinfo",
state = "_" + (+new Date());
Wechat.auth(scope, state, function (response) {
// you may use response.code to get the access token.
alert(JSON.stringify(response));
}, function (reason) {
alert("Failed: " + reason);
});
}
weiboLogin(){}
FBLogin(){
this.fb.login(['email', 'public_profile']).then((response: FacebookLoginResponse) => {
this.fb.api('me?fields=id,name,email,first_name,picture.width(360).height(360).as(picture_large)', []).then(profile => {
this.userData.login({email: profile['email'], first_name: profile['first_name'], picture: profile['picture_large']['data']['url'], username: profile['name']});
});
});
}
}

Ionic 2 push child view inside the tabs View with side navigation

I have a problem in ionic 2+ menu navigation with tabs. When I click the navigation menu, how to access the child view inside the tabs view?
I found some solutions to access the tabs Rootpage but so far I couldn't access the Child view. If I push the child view Directly in app.component.ts the tabs are gone away. It will be hiding itself.
Here is my app.component.ts
import { AboutPage } from './../pages/about/about';
import { Component, ViewChild } from '#angular/core';
import { Events, MenuController, Nav, Platform, NavController } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { App } from 'ionic-angular';
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;
index?: number;
tabName?: string;
tabComponent?: any;
}
#Component({
templateUrl: 'app.template.html'
})
export class TestApp {
#ViewChild(Nav) nav: Nav;
#ViewChild('mycontent') childNavCtrl: NavController;
appPages: PageInterface[] = [
{ title: 'ABOUT US', name: 'TabsPage', component: TabsPage, tabComponent: AboutPage, index: 3, icon: 'assets/img/about-small.png' },
];
rootPage: any;
constructor(
public events: Events,
public userData: UserData,
public menu: MenuController,
public platform: Platform,
public confData: ConferenceData,
public storage: Storage,
public splashScreen: SplashScreen,
public appCtrl: App,
) {
}
openPage(page: PageInterface) {
let params = {};
if (page.index != null) {
params = { tabIndex: page.index };
}
if (this.nav.getActiveChildNavs() && page.index != undefined) {
// push the view here //
} else {
alert('else');
this.nav.setRoot(page.name, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});
}
Here is my app.modules.ts
#NgModule({
declarations: [
testApp,
AboutPage,
AccountPage,
LoginPage
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(testApp, {}, {
links: [
{ component: TabsPage, name: 'TabsPage', segment: 'tabs-page' },
{ component: GalleryDetailsPage, name: 'Gallery details', segment: 'gallery Details' },
{ component: AboutPage, name: 'About', segment: 'about' },
]
}),
CloudModule.forRoot(cloudSettings),
IonicStorageModule.forRoot()
],
bootstrap: [IonicApp],
entryComponents: [
testApp,
AboutPage,
],
providers: [
{ provide: ErrorHandler, useClass: IonicErrorHandler },
ConferenceData,
UserData,
SocialSharing,
InAppBrowser,
Geolocation,
PostPage,
ImagePicker,
Camera,
SplashScreen
]
})
export class AppModule { }
here is my my app.template.html
<ion-content class="menu-contents">
<ion-list class="menu-con">
<button ion-item class="cus-item" menuClose *ngFor="let p of appPages" (click)="openPage(p)">
<!-- ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon -->
<img [src]="p.icon" class="menu-item-img {{p.title === 'POST' ? 'post-icon' : ''}}" alt=""><span class="menu-item-title">{{p.title}}</span>
</button>
</ion-list>
</ion-content>
here is my tabs page:
import { HomePage } from '../home/home';
import { Component } from '#angular/core';
import { NavParams, MenuController, NavController } from 'ionic-angular';
import { AboutPage } from '../about/about';
import { SchedulePage } from '../dash/schedule';
#Component({
selector : 'tabs-view',
templateUrl: 'tabs-page.html'
})
export class TabsPage {
// set the root pages for each tab
tab1Root:any;
tab2Root: any = SchedulePage;
tab3Root: any = AboutPage;
mySelectedIndex: number;
constructor(
navParams: NavParams,
public menu: MenuController,
public navCtrl: NavController,
) {
this.tab1Root = HomePage;
console.log('ONE', navParams.data);
if (navParams.data.tabIndex != null) {
}
}
ionViewDidLoad() {
this.menu.enable(true);
}
}
here is my tabs.html:
<ion-tabs [selectedIndex]="mySelectedIndex" name="weddingapp" #myTabs>
<ion-tab [root]="tab1Root" tabTitle="" tabIcon="icon-home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="" tabIcon="icon-dash"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="" tabIcon="icon-user" class="custom-icon1">user</ion-tab>
Here is my Shedulepage.ts
#Component({
selector: 'page-schedule',
templateUrl: 'schedule.html'
})
export class SchedulePage {
#ViewChild('scheduleList', { read: List }) scheduleList: List;
constructor(
public alertCtrl: AlertController,
public app: App,
public loadingCtrl: LoadingController,
public modalCtrl: ModalController,
public navCtrl: NavController,
public toastCtrl: ToastController,
public confData: ConferenceData,
public user: UserData,
public menu: MenuController,
navParams: NavParams,
) {
console.log(navParams.data);
}
GotoLinks(val:any){
this.navCtrl.push(ContactPage);
}
If you want to push inside the child then what I have is
import { NavController} from 'ionic-angular';
constructor(public navCtrl: NavController){}
myFunction(){
this.navCtrl.push(SomePage);
}
If you want to push inside the tab page
import { App} from 'ionic-angular';
constructor(public app: App){}
myFunction(){
this.app.getRootNav().push(SomePage);
}