App.html": Error: ENOENT: no such file or directory


#1

I am in the process of upgrading from Ionic 2 beta to Ionic 2 rc3.

I have my app.component.ts file, that worked fine, when it was just displaying a root page. But as soon as I have tried to add menu items from my old working Ionic 2 beta version, I get the error below.

If anyone can advise how I can resolve this, I would appreciate the help.

Compile Error in CLI

[13:14:56]  template error, "E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html": Error: ENOENT: no such
            file or directory, open 'E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html'

Runtime Error in browser console

Unhandled Promise rejection: Failed to load build/app.html ; Zone: meteor-rxjs-zone ; Task: Promise.then ; Value: Failed to load build/app.html undefined  polyfills.js:3:7730
Error: Uncaught (in promise): Failed to load build/app.html
Stack trace:
s@http://localhost:8100/build/polyfills.js:3:8568
s@http://localhost:8100/build/polyfills.js:3:8391
h/<@http://localhost:8100/build/polyfills.js:3:8902
sg</d</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:14040
sg</v</e.prototype.runTask@http://localhost:8100/build/polyfills.js:3:11392
i@http://localhost:8100/build/polyfills.js:3:8021
t/this.invoke@http://localhost:8100/build/polyfills.js:3:15204

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { Storage } from "@ionic/storage";
import { Platform, Events, AlertController, Nav } from 'ionic-angular';
import { StatusBar, Push, Splashscreen } from 'ionic-native';
import { SearchJobsPage } from "../pages/searchjobs/searchjobs";
import { LoginPage } from '../pages/login/login';
import { LogoutPage } from '../pages/logout/logout';
import { PersonModel } from '../pages/model/personModel';
import { ChatsPage } from '../pages/chats/chats';
import { PersonPage } from '../pages/person/person';
import { SearchFavouriteJobsPage } from '../pages/searchfavouritejobs/searchfavouritejobs';
import { SearchPostingsPage } from '../pages/searchpostings/searchpostings';
import { SearchFavouritePostingsPage } from '../pages/searchfavouritepostings/searchfavouritepostings';
import { UtilityService } from '../pages/utils/utilityService';
import { NotificationService } from '../pages/service/notificationService';
import { JobService } from '../pages/service/jobService';
import { JobModel } from '../pages/model/jobModel';
import { MapLocationsPage } from '../pages/maplocations/maplocations';
import { MapRangePage } from '../pages/maprange/maprange';
//import { METEOR_PROVIDERS } from 'angular2-meteor';
// import * as Check from 'meteor/check';
// import * as EJSON from 'meteor/ejson';

//declare let Meteor;

@Component({
  templateUrl: 'build/app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;
  rootPage: any;

  public storage: Storage = null;
  public pages: Array<{ title: string, component: any }>;
  public pages_person: Array<{ title: string, component: any }>;
  public pages_person_admin: Array<{ title: string, component: any }>;
  public menuTitle: string = 'Menu';
  public personModel: PersonModel = null;
  public utilityService: UtilityService = null;
  public notificationService: NotificationService = null;
  public personModelLoggedIn: PersonModel;
  public jobService: JobService = null;
  public events: Events = null;
  public ios: boolean = false;

  constructor(private platform: Platform, utilityService: UtilityService, notificationService: NotificationService, jobService: JobService, events: Events, private alertCtrl: AlertController, storage: Storage) {
    this.storage = storage;
    this.utilityService = utilityService;
    this.jobService = jobService;
    this.notificationService = notificationService;
    this.events = events;
    this.initializeApp();
    if (this.platform.is('ios')) {
      this.ios = true;
    }

    // this.rootPage = Meteor.user() ? TabsPage : LoginComponent;
    this.rootPage = SearchJobsPage;

    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.initializeApp();
      StatusBar.styleDefault();
      Splashscreen.hide();
    });

    // used for an example of ngFor and navigation
    this.pages = [
      { title: 'Market', component: SearchJobsPage },
      { title: 'Postings', component: SearchPostingsPage },
      { title: 'Login', component: LoginPage }
    ];

    this.pages_person = [
      { title: 'Market', component: SearchJobsPage },
      { title: 'Market Favourites', component: SearchFavouriteJobsPage },
      { title: 'Postings', component: SearchPostingsPage },
      { title: 'Favourite Postings', component: SearchFavouritePostingsPage },
      { title: 'Messages', component: ChatsPage },
      { title: 'Profile', component: PersonPage },
      { title: 'Logout', component: LogoutPage }
    ];

    this.pages_person_admin = [
      { title: 'Market', component: SearchJobsPage },
      { title: 'Market Favourites', component: SearchFavouriteJobsPage },
      { title: 'Postings', component: SearchPostingsPage },
      { title: 'Favourite Postings', component: SearchFavouritePostingsPage },
      { title: 'Messages', component: ChatsPage },
      { title: 'Profile', component: PersonPage },
      { title: 'Logout', component: LogoutPage },
      { title: 'Map Locations', component: MapLocationsPage },
      { title: 'Map Range', component: MapRangePage }
    ];
  }

  initializeApp() {
    StatusBar.styleDefault();
    this.checkLogin();
    this.utilityService.startUpChecks();
    if (window['cordova']) {
      this.utilityService.setLocalStrorage('this.chats.observe', 'false');
      this.utilityService.setLocalStrorage('this.messages.observe', 'false');
      this.utilityService.setLocalStrorage('this.messages.subscribe', 'false');
      this.utilityService.setLocalStrorage('push:notifications.subscribe', 'false');
    }
    this.subscribeEvents();
  }

  // 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);
  // }

  public subscribeEvents(): void {
    this.events.subscribe('push:notifications', (data) => {
      this.checkLogin();
    });
  }

  public pushNotifications(): void {
    let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('push:notifications.subscribe');
    observedPromise.then((observed: string) => {
      if (!observed || observed != 'true') {
        this.utilityService.setLocalStrorage('push:notifications.subscribe', 'true');
        try {
          if (window['cordova']) {
            if (this.personModelLoggedIn) {
              let promiseJobsForPerson: Promise<JobModel[]> = this.jobService.getJobsByPerson(this.personModelLoggedIn.id);
              promiseJobsForPerson.then((data) => {
                let jobModelsForPerson: JobModel[] = data;
                let topics: string[] = [];
                topics.push('P' + this.personModelLoggedIn.id);
                for (let i = 0; i < jobModelsForPerson.length; i++) {
                  let jobModel: JobModel = jobModelsForPerson[i];
                  topics.push('J' + jobModel.id);
                }

                //topics.push('J65'); // deleteme
                //topics.push('P9'); // deleteme

                let push = Push.init({
                  android: {
                    senderID: "893141127008",
                    topics: topics
                  },
                  ios: {
                    alert: "true",
                    badge: false,
                    sound: "true",
                    topics: topics
                  },
                  windows: {}
                });

                push.on('registration', (data1) => {
                  this.events.subscribe('messages:notify', (data) => {
                    let promise: Promise<string> = this.notificationService.push('null', data[0].topic, data[0].message, data[0].title);
                    promise.then((data2) => {
                      // console.log('app.ts messages2:notify', data2);
                    });
                  });
                });
                push.on('notification', (data) => {
                  this.events.publish('messages:update');
                  if (this.nav.getActive().name != 'ChatsPage' && this.nav.getActive().name != 'MessagesPage') {
                    //if user using app and push notification comes
                    if (data.additionalData.foreground) {
                      //if application open, show popup
                      let confirmAlert = this.alertCtrl.create({
                        title: data.title,
                        message: data.message,
                        buttons: [{
                          text: 'Ignore',
                          role: 'cancel'
                        }, {
                          text: 'View',
                          handler: () => {
                            this.rootPage = ChatsPage;
                          }
                        }]
                      });
                      confirmAlert.present(confirmAlert);
                    } else {
                      this.rootPage = ChatsPage;
                    }
                  }
                });
                push.on('error', (e) => {
                  alert('Error: ' + e.message);
                  console.log(e);
                });
              });
            }
          }
        } catch (e) {
          alert('Push Notification: ' + e.message());
          console.log('Push Notification: ' + e.message());
        }
      }
    });
  }

  public checkLogin(): void {
    let promise: Promise<string> = this.utilityService.getLoggedInPerson();
    promise.then((data) => {
      this.personModelLoggedIn = JSON.parse(data);
      if (this.personModelLoggedIn) {
        this.utilityService.setUpMenuItems();
        this.pushNotifications();
      }
    });
  }
}

app.html

<ion-menu [content]="content" id="unauthenticated">
  <ion-toolbar>
    <ion-title>Menu</ion-title>
  </ion-toolbar>
  <ion-content>
    <ion-list>
      <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
        {{p.title}}
      </button>
    </ion-list>
  </ion-content>
</ion-menu>

<ion-menu [content]="content" id="authenticated-person">
  <ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
    <ion-title [class]="ios ? 'menu-title' : ''">
      <div class="item-avatar-img" id="menu-item-avatar-img-person"></div>
      <div class="item-avatar-name" id="menu-item-avatar-name-person"></div>
    </ion-title>
  </ion-toolbar>
  <ion-content>
    <ion-list>
      <button menuClose ion-item *ngFor="let p of pages_person" (click)="openPage(p)">
        {{p.title}}
      </button>
    </ion-list>
  </ion-content>
</ion-menu>

<ion-menu [content]="content" id="authenticated-person-admin">
  <ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
    <ion-title [class]="ios ? 'menu-title' : ''">
      <div class="item-avatar-img" id="menu-item-avatar-img-person-admin"></div>
      <div class="item-avatar-name" id="menu-item-avatar-name-person-admin"></div>
    </ion-title>
  </ion-toolbar>
  <ion-content>
    <ion-list>
      <button menuClose ion-item *ngFor="let p of pages_person_admin" (click)="openPage(p)">
        {{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>

Directory

enter image description here


#2

change it to templateUrl: 'app.html'