getting Nav as undefined in root page - ionic-framework

I recently upgraded from Ionic 2 to Ionic 3. As soon as I upgraded, I am getting Nav as undefined in root page.
//app.component.ts
import { Component, ViewChild, Renderer } from '#angular/core';
import { Platform, Nav, MenuController } from 'ionic-angular';
#Component({
templateUrl: `app.html`
})
export class MyApp {
#ViewChild(Nav) nav : NavController ;
rootPage: any;
authHandler : any;
pages: Array<{title: string, component: any, icon: string}>;
urls: Array<{title: string, url: string, icon: string}>;
contact: Array<{title: string, url: string, icon: string}>;
constructor(public platform: Platform,
public renderer : Renderer,
public menu: MenuController,
public loginService : LoginService,
public util : UtilityService,
public statusBar: StatusBar,
public keyboard: Keyboard) {
this.initializeApp();
console.log("THis is nav object :: ", this.nav);
}
//app.html
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
output in the console:
THis is nav object :: undefined
Is something changed in Ionic 3 what I have to do In order to make that work?

you have to use ion-nav template
#Component({
template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
})
like describe here : https://ionicframework.com/docs/api/navigation/NavController/#navigating-from-the-root-component
Or you can add ion-nav tag in your app.html :
<ion-nav id="nav" [root]="rootPage" #content swipe-back-enabled="false"></ion-nav>

Related

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(RegisterPageModule)[AccessProviders -> AccessProviders]

I have a problem in my Ionic app with AngularJS, in register.page.ts; when i am going to add the AccessProviders path in the project the project says:ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(RegisterPageModule)[AccessProviders -> AccessProviders -> AccessProviders -> AccessProviders]: NullInjectorError: No provider for AccessProviders!
I have created the access providers folder and files manually.
register.page.ts
import {Router} from "#angular/router";
import { ToastController, LoadingController, AlertController } from "#ionic/angular";
import {AccessProviders} from "../../providers/access-providers";
#Component({
selector: 'app-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
name: string = "";
gender: string = "";
dob: string = "";
email: string = "";
password: string = "";
confirm_password: string = "";
disabledButton;
constructor(
private router: Router,
private toastCtrl: ToastController,
private alertCtrl: AlertController,
private loadingCtrl: LoadingController,
private accsPrvds: AccessProviders,
) { }
ionViewDidEnter() {
this.disabledButton = false;
}
access-providers.ts
import { HttpClient, HttpHeaders, HttpErrorResponse } from "#angular/common/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/timeout';
#Injectable()
export class AccessProviders {
server: string = 'http://localhost:8100/register'; //should change.
constructor(
public http: HttpClient
) {
}
postData(body, file) {
let headers = new HttpHeaders({
'Content-Type': 'application/json; charset=UTF-8'
});
let options = {
headers: headers
};
return this.http.post(this.server + file, JSON.stringify(body), options)
.timeout(59000)// 59 sec timeout
.map(res => res);
}
}
How i can solve this problem? I hope got my answer.
ADD blow code inside your access-providers.ts file:
import { Injectable } from '#angular/core'; // at top
#Injectable({
providedIn: 'root' // just before your class
})
export class AccessProviders {}
Make sure that HttpClientModule is registered at the level of AppModule
Just add this in your app.module.ts
import { HttpClientModule } from '#angular/common/http'
/////
#NgModule({
imports: [ HttpClientModule ]
})
It looks like you need to add it under providers in your app.modules.ts file.
If you only need the class in one page you could add it to the page.module.ts file of the corresponding page.
I had a similar problem, I found my solution here:
https://github.com/angular/angular/issues/20339#issuecomment-354767429
I had to import
"import {HttpClientModule} from '# angular / common / http';" in
imports: [HttpClientModule], inside the module that references the component.
In your app module
You have to add at the top :
import {AccessProviders} from "../../providers/access-providers";
On the same file, find providers and just add AccessProviders to the list of providers.

deep links not working - ionic

im using deeplinks and ionic 3, but the url i created not working.
this is the url : https://lucky.com/prd/rm74fEgBB2frzhagYcov
this is my code :
this.deepLinks.route({
'/prd/:id': ProductDetailsPage,
'/rcm/:id': RecommendationDetailsPage
})
.subscribe((match) => {
console.log(match);
}, (nomatch) => {
console.log(nomatch);
});
he doesnt go to the subscribe function, either nor to the match or nomatch
what is my problem ?
Please check this
import {Component, ViewChild} from '#angular/core';
import {Platform, Nav} from 'ionic-angular';
import {StatusBar} from '#ionic-native/status-bar';
import {SplashScreen} from '#ionic-native/splash-screen';
import {Deeplinks} from '#ionic-native/deeplinks';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: string = 'DashboardPage';
#ViewChild(Nav) nav: Nav;
constructor(public platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private deeplinks: Deeplinks) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
if (platform.is('cordova')) {
this.deeplinks.routeWithNavController(this.nav, {
'/event/:year/:month/:eventItem/:title': 'ScheduleDetails',
'/email/verify/': 'Login',
'/password/reset/:token': 'ChangePassword',
'/prd/:id': 'ProductDetailsPage',
'/rcm/:id': 'RecommendationDetailsPage'
}).subscribe((match) => {
// console.log('success' + JSON.stringify(match));
}, (noMatch) => {
// alert('error' + JSON.stringify(noMatch));
// console.log('error' + JSON.stringify(noMatch));
});
}
});
}
}
And don't forgot to add providers as Deeplinks in app.module.ts file

How to properly implement leaflet search in Ionic 3?

I am trying to search location in the leaflet map. I am using leaflet-search plugin to achieve this. I tried the following code:
import {Component} from '#angular/core';
import {IonicPage, NavController, NavParams} from 'ionic-angular';
import 'leaflet';
import 'leaflet-routing-machine';
import 'leaflet-search'
declare var L: any;
#IonicPage()
#Component({
selector: 'page-map-modal',
templateUrl: 'map-modal.html',
})
export class MapModalPage {
map: L.Map;
center: L.PointTuple;
searchControl: any;
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
leafletMap() {
this.map = L.map('mapId', {
center: this.center,
zoom: 16
});
let searchLayer = L.layerGroup().addTo(this.map);
this.map.addControl(new L.Control.Search({layer: searchLayer}));
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attributionControl: false,
maxNativeZoom: 17,
maxZoom: 17
}
).addTo(this.map);
}
ionViewDidLoad() {
this.center = [23.762912, 90.430693];
this.leafletMap();
}
}
The search icon css is not loaded properly.
Then, when i tried to search for a location, location not found shows.
What's the perfect way to include leaflet-search. I want below features:
How to show suggestion when typing for a location?
How to give preference to show the locations of Bangladesh when typing for location?

ionic 2/3: How to select tabs dynamically

I created a sidemenu app in Ionic 2 which contains a Main Tab and 3 sub tab pages.
It looks like this:
This is the code for Main tabs page:
<ion-header>
<ion-navbar #content color="black">
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title >Main Tab</ion-title>
</ion-navbar>
</ion-header>
<ion-tabs [selectedIndex]="mySelectedIndex" #myTabs>
<ion-tab [root]="tabARoot" tabTitle="Tab A" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tabBRoot" tabTitle="Tab B" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tabCRoot" tabTitle="Tab C" tabIcon="information-circle"></ion-tab>
</ion-tabs>
It contains 3 sub tab pages with some gibberish on it.
This is how my side menu looks like.
So when a user clicks on Tab B link from side menu, he should navigate to main tabs page with Tab B as selected. But now when I click, Tab A is selected by default.
Is it possible to change this behavior?
My app.component.ts file looks like this
import { Component, ViewChild } from '#angular/core';
import { Nav, Platform, App, Tabs } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { MainPage } from '../pages/main/main';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any = MainPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, private app: App) {
this.initializeApp();
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Tab A', component: MainPage },
{ title: 'Tab B', component: MainPage },
{ title: 'Tab C', component: MainPage },
];
}
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
From somewhere I got a solution which didn't work, obviously.
in that solution, it was mentioned to do it like given below but it didn't work'
this.nav.setRoot(page.component, {tabIndex: 2});
There is a property called selectedIndex in ion-tabs component to set the default tab. Since you are passing tabIndex while clicking the main tab you can do something like this
In the controller
selectedTabIndex = navParams.get('tabIndex');
In the view
<ion-tabs [selectedIndex]="selectedTabIndex">
<ion-tab [root]="tabA"></ion-tab>
<ion-tab [root]="tabB"></ion-tab>
<ion-tab [root]="tabC"></ion-tab>
</ion-tabs>
Else if you want to select any tabs programatically from controller you can do this, first get the reference of your tabs and then you can use the select() function to set the selected tab you want by passing the index
#ViewChild('myTabs') tabRef: Tabs;
ionViewDidLoad() {
this.tabRef.select(1, { animate: false });
}
#john Doe
set root page = 'MenuPage' page
rootPage = 'MenuPage'
try below code:
`
src/pages/menu/menu.html :
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item menuClose *ngFor="let p of pages" (click)="openPage(p)">
<ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
{{ p.title }}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- main navigation -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
src/pages/menu/menu.ts:
import { Tab2Page } from './../tab2/tab2';
import { Tab1Page } from './../tab1/tab1';
import { TabsPage } from './../tabs/tabs';
import { Component, ViewChild } from '#angular/core';
import { IonicPage, NavController, Nav } from 'ionic-angular';
export interface PageInterface {
title: string;
pageName: string;
tabComponent?: any;
index?: number;
icon: string;
}
#IonicPage()
#Component({
selector: 'page-menu',
templateUrl: 'menu.html',
})
export class MenuPage {
// Basic root for our content view
rootPage = 'TabsPage';
// Reference to the app's root nav
#ViewChild(Nav) nav: Nav;
pages: PageInterface[] = [
{ title: 'Tab 1', pageName: 'TabsPage', tabComponent: 'Tab1Page', index: 0, icon: 'home' },
{ title: 'Tab 2', pageName: 'TabsPage', tabComponent: 'Tab2Page', index: 1, icon: 'contacts' },
{ title: 'Special', pageName: 'SpecialPage', icon: 'shuffle' },
];
constructor(public navCtrl: NavController) { }
openPage(page: PageInterface) {
let params = {};
// The index is equal to the order of our tabs inside tabs.ts
if (page.index) {
params = { tabIndex: page.index };
}
// The active child nav is our Tabs Navigation
if (this.nav.getActiveChildNav() && page.index != undefined) {
this.nav.getActiveChildNav().select(page.index);
} else {
// Tabs are not active, so reset the root page
// In this case: moving to or from SpecialPage
this.nav.setRoot(page.pageName, params);
}
}
isActive(page: PageInterface) {
// Again the Tabs Navigation
let childNav = this.nav.getActiveChildNav();
if (childNav) {
if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
return 'primary';
}
return;
}
// Fallback needed when there is no active childnav (tabs not active)
if (this.nav.getActive() && this.nav.getActive().name === page.pageName) {
return 'primary';
}
return;
}
}
src/pages/tabs/tabs.html
<ion-tabs [selectedIndex]="myIndex">
<ion-tab [root]="tab1Root" tabTitle="Tab 1" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="Tab 2" tabIcon="contacts"></ion-tab>
</ion-tabs>
src/pages/tabs/tabs.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-tabs',
templateUrl: 'tabs.html',
})
export class TabsPage {
tab1Root: any = 'Tab1Page';
tab2Root: any = 'Tab2Page';
myIndex: number;
constructor(navParams: NavParams) {
// Set the active tab based on the passed index from menu.ts
this.myIndex = navParams.data.tabIndex || 0;
}
}
thanks

Accordion List within ionic 2

I've create a custom components named Accordion within iconic 2 and working in browser perfectly but on device not working.
I've split my code up into components, where
Home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {DataCards} from '../../components/data-cards/data-cards';
import {Data} from '../../components/data/data';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public dataList: Data[];
constructor(public navCtrl: NavController) {
this.dataList = [
new Data('title 1', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-remove-circle-outline', true),
new Data('title 2', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-add-circle-outline', false),
new Data('title 3', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-add-circle-outline', false)
];
}
}
and the corresponding HTML
<ion-content padding>
<data-cards [data]="dataList"></data-cards>
</ion-content>
contain my custom component data-cards. data-cards has an input parameter data, through which the list of data is passed.
data.ts
import { Component } from '#angular/core';
#Component({
selector: 'data',
templateUrl: 'data.html'
})
export class Data {
constructor(public title: string, public details: string, public icon: string, public showDetails: boolean) {}
}
data-cards.ts
import { Component } from '#angular/core';
import { Data } from '../data/data';
#Component({
selector: 'data-cards',
inputs: ['data'],
templateUrl: 'data-cards.html'
})
export class DataCards {
public data: Data[];
constructor() {}
toggleDetails(data: Data) {
if (data.showDetails) {
data.showDetails = false;
data.icon = 'ios-add-circle-outline';
} else {
data.showDetails = true;
data.icon = 'ios-remove-circle-outline';
}
}
}
app.module.ts
import { NgModule } from '#angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Data } from '../components/data/data';
import { DataCards } from '../components/data-cards/data-cards';
#NgModule({
declarations: [
MyApp,
HomePage,
Data,
DataCards
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
Data,
DataCards
],
providers: []
})
export class AppModule {}
When run on iOS ( ionic run ios ) i've got an error like below :
[08:44:54] Error: Error at /Users/imac/Documents/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:71
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:111
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:151
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:191
[08:44:54] Property 'boolean' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] ngc failed
[08:44:54] ionic-app-script task: "build"
[08:44:54] Error: Error
so my question : how i can resolve this problem any suggestion ?
In data-card.ts change
public data: Data[];
o be
Input() data: Data[];
since you will be assigning it from the component creation in the home.html? You'll also need to import the Input module via
import { Component, Input } from '#angular/core';