1
votes

I am getting Error:

Uncaught (in promise): Error: No provider for NavController!

This was working earlier with ionic 2, but once i upgrade to ionic 3 i started getting issues.

Any help on this is required, I have also observed that once i remove the HttpClient import from LoginServer.ts it will work proper, So not sure whether its a problem with Angular 4 Http Module.

Here is the Code

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler, NavController } from 'ionic-angular';
import { MyApp } from './app.component';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { HelloIonicPage } from '../pages/hello-ionic/hello-ionic';
import { ItemDetailsPage } from '../pages/item-details/item-details';
import { ListPage } from '../pages/list/list';
import { ContactsPage } from '../pages/contacts/contacts';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { IonicStorageModule } from '@ionic/storage';
import { B2BSearchPage } from  '../pages/b2bsearch/b2bsearch';
import { LoginPage } from  '../pages/login/login';
import { RegisterPage } from '../pages/register/register';
import { LogoutPage } from '../pages/logout/logout';
import { UserService } from  '../service/user/userService';
import { MasterConfig } from '../config/config';
import { QuicksearchPage } from '../pages/quicksearch/quicksearch';
import { BookingPage } from '../pages/booking/booking';
import { BookingconfirmationPage } from '../pages/bookingconfirmation/bookingconfirmation';
import { InvoicePage } from '../pages/invoice/invoice';
import { EditbookingPage } from '../pages/editbooking/editbooking';
import { B2CsearchPage } from '../pages/b2-csearch/b2-csearch';
import { CityService } from '../service/common/cityService';
import { StatusService } from '../service/common/statusService';
import { HTTP_INTERCEPTORS  } from '@angular/common/http';
import { TokenInterceptor } from '../service/interceptor/tokenInterceptor';

@NgModule({
  declarations: [
    MyApp,
    HelloIonicPage,
    ItemDetailsPage,
    ListPage,
    ContactsPage,
    B2BSearchPage,
    LoginPage,
    RegisterPage,
    LogoutPage,
    QuicksearchPage,
    BookingPage,
    BookingconfirmationPage,
    InvoicePage,
    EditbookingPage,
    B2CsearchPage
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot()
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HelloIonicPage,
    ItemDetailsPage,
    ListPage,
    ContactsPage,
    B2BSearchPage,
    LoginPage,
    RegisterPage,
    LogoutPage,
    QuicksearchPage,
    BookingPage,
    BookingconfirmationPage,
    InvoicePage,
    EditbookingPage,
    B2CsearchPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    MasterConfig,
    CityService,
    StatusService,
    UserService,
    HttpClientModule,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    }
  ]
})
export class AppModule {}

app.component.ts

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

import { Platform, MenuController, Nav ,NavController} from 'ionic-angular';

import { HelloIonicPage } from '../pages/hello-ionic/hello-ionic';
import { ListPage } from '../pages/list/list';
import { ContactsPage } from '../pages/contacts/contacts';
import { B2BSearchPage } from '../pages/b2bsearch/b2bsearch';
import { LoginPage } from '../pages/login/login';
import { RegisterPage } from '../pages/register/register';
import { LogoutPage } from '../pages/logout/logout';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Storage } from '@ionic/storage';
import { Events } from 'ionic-angular';
import { QuicksearchPage } from '../pages/quicksearch/quicksearch';
import { BookingPage } from '../pages/booking/booking';
import { B2CsearchPage } from '../pages/b2-csearch/b2-csearch';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild('content') nav: NavController;

  HAS_LOGGED_IN = 'hasLoggedIn';

  // make HelloIonicPage the root (or first) page
  rootPage = HelloIonicPage;
  pages: Array<{title: string, component: any}>;
  username :String;

  constructor(
    public platform: Platform,
    public menu: MenuController,
    public statusBar: StatusBar,
    public splashScreen: SplashScreen,
    public storage: Storage,
    public events: Events
  ) {
    this.initializeApp();

    storage.get(this.HAS_LOGGED_IN).then((val) => {
      storage.get("username").then((val) => {
        this.username = val;
      });
      this.pages = [
        { title: 'Search B2B Booking', component: B2BSearchPage },
        { title: 'Search B2C Booking', component: B2CsearchPage },
        { title: 'Create Booking', component: BookingPage },
        { title: 'Quick B2C Search', component: QuicksearchPage },
        { title: 'Logout', component: LogoutPage }
      ];
      if (null === val) {
        this.pages = [
          { title: 'Login', component: LoginPage },
          { title: 'Register', component: RegisterPage }
        ];
      }
    });

    events.subscribe('user.logout', () => {
      this.pages = [
        { title: 'Login', component: LoginPage },
        { title: 'Register', component: RegisterPage }
      ];
    });

    events.subscribe('user.login', () => {
      this.pages = [
        { title: 'Search B2B Booking', component: B2BSearchPage },
        { title: 'Search B2C Booking', component: B2CsearchPage },
        { title: 'Create Booking', component: BookingPage },
        { title: 'Quick B2C Search', component: QuicksearchPage },
        { title: 'Logout', component: LogoutPage }
      ];
    });
  }

  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) {
    // close the menu when clicking a link from the menu
    this.menu.close();
    // navigate to the new page if it is not the current page
    this.nav.push(page.component);
  }

  home(){
    this.nav.setRoot(HelloIonicPage);
  }

  search(){
    this.nav.setRoot(QuicksearchPage);
  }

  createBooking(){
    this.nav.setRoot(BookingPage);
  }
}

login.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Storage } from '@ionic/storage';
import { B2BSearchPage } from '../b2bsearch/b2bsearch';
import { Events } from 'ionic-angular';
import { MasterConfig } from '../../config/config';
import { ProviderMeta } from '@angular/compiler';
import {LoginService} from '../../service/user/loginService';

@IonicPage()
@Component({
    selector: 'login-list',
    templateUrl: 'login.html',
    providers:[LoginService]
})
export class LoginPage implements OnInit {

    user: FormGroup;
    loginFailure = true;
    HAS_LOGGED_IN = 'hasLoggedIn';

    constructor(
        public navCtrl: NavController, 
        public storage: Storage,
        public events: Events,
        public masterConfig:MasterConfig,
        public loginService:LoginService ) {
    }
    ngOnInit() {
        this.user = new FormGroup({
            username: new FormControl('', [Validators.required, Validators.maxLength(20)]),
            password: new FormControl('', [Validators.required, Validators.maxLength(15)]),
        });
    }

    onSubmit(formData) {
        this.loginService.loginUser(formData).then((data) =>{
            console.log(data);
        }).catch((error)=>{
            console.log(error);
        })
    }
}

loginService.ts

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map, catchError } from 'rxjs/operators';
import { MasterConfig } from '../../config/config';

@Injectable()
export class LoginService {

    object = {
        username: "",
        token: "",
        userType: "ANDRIOD"
    }
    constructor(
        public http: HttpClient,
        public storage: Storage,
        public masterConfig: MasterConfig) {

        storage.get('token').then((val) => {
            this.object.token = val;
        });
        storage.get('username').then((val) => {
            this.object.username = val;
        });
    }

    loginUser(formData) {

        var url = this.masterConfig.AUTH_SERVER_URL + "/login";
        console.log(url);
        var data = JSON.stringify({ username: formData.controls.username.value, password: formData.controls.password.value, userType: "ANDRIOD" });

        return new Promise((resolve, reject) => {
            var dataObj = JSON.stringify({ username: this.object.username, token: this.object.token, userType: this.object.userType });

            this.http.post(url, dataObj).subscribe(data => {
               console.log(data);
                resolve(data);
            }, error => {
                reject(error);
            });
        });  
    }
}

package.json

 {
  "name": "MyIonicProject",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "^4.4.7",
    "@angular/compiler": "^4.4.7",
    "@angular/compiler-cli": "^4.4.7",
    "@angular/core": "^4.4.7",
    "@angular/forms": "^4.4.7",
    "@angular/http": "^4.4.7",
    "@angular/platform-browser": "^4.4.7",
    "@angular/platform-browser-dynamic": "^4.4.7",
    "@ionic-native/core": "^3.14.0",
    "@ionic-native/splash-screen": "^3.14.0",
    "@ionic-native/status-bar": "^3.14.0",
    "@ionic/storage": "^2.0.1",
    "cordova-android": "^6.2.3",
    "cordova-plugin-compat": "^1.0.0",
    "cordova-plugin-device": "^1.1.4",
    "cordova-plugin-geolocation": "^2.4.3",
    "cordova-plugin-splashscreen": "^4.0.3",
    "cordova-plugin-statusbar": "^2.2.2",
    "cordova-plugin-whitelist": "^1.3.1",
    "cordova-sqlite-storage": "^2.0.4",
    "ionic-angular": "^3.9.2",
    "ionic-plugin-keyboard": "^2.2.1",
    "ionicons": "^3.0.0",
    "rxjs": "^5.5.11",
    "sw-toolbox": "^3.6.0",
    "zone.js": "^0.8.26"
  },
  "devDependencies": {
    "@ionic/app-scripts": "2.1.4",
    "typescript": "2.3.4"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-sqlite-storage": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-whitelist": {},
      "ionic-plugin-keyboard": {},
      "cordova-plugin-geolocation": {}
    },
    "platforms": [
      "android"
    ]
  }
}
1

1 Answers

0
votes

Use the HttpClient from HttpClientModule if you're using Angular 4.3.x and above. It's the new version of HttpModule which comes with features like: Automatic conversion from JSON to an object, Response type definition... HttpModulein the other hand is now deprecated (refer to Documentation).

Another issue here is that you should never inject Navcontroller into your app.component.ts.