I am trying to upgrade from Beta 6 to Beta 8 but can’t get my code to work anymore.
I followed your instructions to upgrade from 6 to 7 and then your instructions for upgrading from 7 to 8. Now when I do:
ionic serve —lab
I get a blank page with the following browser error:
Error: Uncaught (in promise): Template parse errors:
Can't bind to 'ngFor' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
"): ConferenceApp@19:33
Can't bind to 'ngForP' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
"): ConferenceApp@19:33
Property binding ngFor not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon ["): ConferenceApp@19:6
Property binding ngForP not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon ["): ConferenceApp@19:6
Can't bind to 'ngFor' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of loggedOutPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>"): ConferenceApp@31:33
Can't bind to 'ngForP' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of loggedOutPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>"): ConferenceApp@31:33
Property binding ngFor not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of loggedOutPages" (click)="openPage(p)">
<ion-icon "): ConferenceApp@31:6
Property binding ngForP not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of loggedOutPages" (click)="openPage(p)">
<ion-icon "): ConferenceApp@31:6
Can't bind to 'ngFor' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
"): ConferenceApp@42:33
Can't bind to 'ngForP' since it isn't a known native property ("
</ion-list-header>
-->
<button ion-item menuClose [ERROR ->]*ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
"): ConferenceApp@42:33
Property binding ngFor not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon [name]"): ConferenceApp@42:6
Property binding ngForP not used by any directive on an embedded template ("
</ion-list-header>
-->
[ERROR ->]<button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon [name]"): ConferenceApp@42:6
Stack trace:
resolvePromise@http://localhost:8100/build/js/zone.js:538:32
resolvePromise@http://localhost:8100/build/js/zone.js:523:18
scheduleResolveOrReject/<@http://localhost:8100/build/js/zone.js:571:18
Zone</ZoneDelegate</ZoneDelegate.prototype.invokeTask@http://localhost:8100/build/js/zone.js:356:24
Zone</Zone</Zone.prototype.runTask@http://localhost:8100/build/js/zone.js:256:29
drainMicroTaskQueue@http://localhost:8100/build/js/zone.js:474:26
ZoneTask/this.invoke@http://localhost:8100/build/js/zone.js:426:22
———————
My package.json
looks like this:
{
"dependencies": {
"@angular/common": "^2.0.0-rc.1",
"@angular/compiler": "^2.0.0-rc.1",
"@angular/core": "^2.0.0-rc.1",
"@angular/http": "^2.0.0-rc.1",
"@angular/platform-browser": "^2.0.0-rc.1",
"@angular/platform-browser-dynamic": "^2.0.0-rc.1",
"@angular/router": "^2.0.0-rc.1",
"es6-promise": "3.0.2",
"es6-shim": "^0.35.0",
"ionic-angular": "^2.0.0-beta.8",
"ionic-native": "^1.2.0",
"ionicons": "3.0.0-alpha.3",
"iphone-inline-video": "^1.4.0",
"reflect-metadata": "^0.1.2",
"rxjs": "^5.0.0-beta.6",
"zone.js": "^0.6.12"
},
"devDependencies": {
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-preset-es2015": "6.6.0",
"babelify": "7.2.0",
"del": "2.2.0",
"gulp": "3.9.1",
"gulp-watch": "4.3.5",
"ionic-gulp-browserify-es2015": "^1.0.0",
"ionic-gulp-fonts-copy": "^1.0.0",
"ionic-gulp-html-copy": "^1.0.0",
"ionic-gulp-sass-build": "^1.0.0",
"ionic-gulp-scripts-copy": "^2.0.0"
},
"cordovaPlugins": [
"cordova-plugin-device",
"cordova-plugin-console",
"cordova-plugin-whitelist",
"cordova-plugin-splashscreen",
"cordova-plugin-statusbar",
"ionic-plugin-keyboard"
],
"cordovaPlatforms": [
"ios",
{
"platform": "ios",
"version": "",
"locator": "ios"
},
"android"
],
"name": "VeeU",
"description": "VeeU: Exposing digital media to a wider audience”
}
Any ideas what I need to do to fix this?
EDIT:
Here is the app.html
code containing the ngFor
:
<!-- left menu -->
<ion-menu [content]="content">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content class="outer-content">
<ion-list>
<ion-list *ngIf="loggedIn">
<!--
<ion-list-header>
Account
</ion-list-header>
-->
<button ion-item menuClose *ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
{{p.title}}
</button>
</ion-list>
<ion-list *ngIf="!loggedIn">
<!--
<ion-list-header>
Account
</ion-list-header>
-->
<button ion-item menuClose *ngFor="let p of loggedOutPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
{{p.title}}
</button>
</ion-list>
<!--
<ion-list-header>
Navigate
</ion-list-header>
-->
<button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon [name]="p.icon"></ion-icon>
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- main navigation -->
<ion-nav id="nav" [root]="root" #content swipe-back-enabled="false"></ion-nav>
And here is the associated app.js
code:
import {ionicBootstrap, App, Events, Platform, MenuController, Storage, SqlStorage} from 'ionic-angular';
import {File, StatusBar} from 'ionic-native';
import {ViewChild, Component, Inject} from '@angular/core';
import {ConferenceData} from './providers/conference-data';
import {MediaItemData} from './providers/item-data';
import {UserData} from './providers/user-data';
import {TabsPage} from './pages/tabs/tabs';
import {LoginPage} from './pages/login/login';
import {SignupPage} from './pages/signup/signup';
import {TutorialPage} from './pages/tutorial/tutorial';
import {PhotoPage} from './pages/photo/photo';
import {SettingsPage} from './pages/settings/settings';
import {AboutPage} from './pages/about/about';
import {VeeUPage} from './pages/veeu/veeu';
import {MyItemsPage} from './pages/my-items/my-items';
import {BookmarksPage} from './pages/bookmarks/bookmarks';
import {ProfilePage} from './pages/profile/profile';
import {API_ENDPOINT} from '../app_settings';
/* OLD IONIC BETA 6
@App({
templateUrl: 'build/app.html',
providers: [ConferenceData, UserData, MediaItemData],
queries: {
nav: new ViewChild('content')
},
config: {
platforms: {
android: {
tabbarLayout: 'icon-hide'
}
}
}
})
*/
@Component({
templateUrl: 'build/app.html',
})
export class ConferenceApp {
static get parameters() {
return [[App], [Events], [ConferenceData], [UserData], [MediaItemData], [Platform], [MenuController]]
}
constructor(app, events, confData, userData, mediaItemData, platform, menu) {
this.app = app;
this.userData = userData;
this.events = events;
this.menu = menu;
this.platform = platform;
this.loggedIn = false;
this.menu.swipeEnable(true);
/*
this.platform.ready().then(() => {
var push = Push.init({
android: {
senderID: "12345679"
},
ios: {
alert: "true",
badge: true,
sound: 'false'
},
windows: {}
});
});
*/
// :PUSH: Onesignal BAAS
document.addEventListener('deviceready', function () {
//alert('Device Ready');
// Enable to debug issues.
// window.plugins.OneSignal.setLogLevel({logLevel: 4, visualLevel: 4});
var notificationOpenedCallback = function(jsonData) {
//alert('didReceiveRemoteNotificationCallBack: ' + JSON.stringify(jsonData));
};
window.plugins.OneSignal.init("ad1fbf91-bd63-43a7-ad02-f7739f4b4b7a",
{googleProjectNumber: "xxxxxx"},
notificationOpenedCallback);
// Show an alert box if a notification comes in when the user is in your app.
window.plugins.OneSignal.enableInAppAlertNotification(true);
}, false);
// Load the media item data
//mediaItemData.loadMediaItems();
// load the conference data
//confData.load();
//alert(API_ENDPOINT);
// MENU...
// create a 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
this.appPages = [
/* Tabs version
{ title: 'Schedule', component: TabsPage, icon: 'calendar' },
{ title: 'Speakers', component: TabsPage, index: 1, icon: 'contacts' },
{ title: 'Map', component: TabsPage, index: 2, icon: 'map' },
{ title: 'About', component: TabsPage, index: 3, icon: 'information-circle' },
*/
{ title: 'About', component: AboutPage, index: 3, icon: 'information-circle' }
];
this.loggedInPages = [
{ title: 'VeeU', component: VeeUPage, icon: 'eye' },
{ title: 'Saved', component: BookmarksPage, icon: 'star' },
{ title: 'Submit image', component: PhotoPage, icon: 'add-circle' },
{ title: 'My images', component: MyItemsPage, icon: 'camera' },
{ title: 'Categories', component: SettingsPage, icon: 'settings' },
{ title: 'Profile', component: ProfilePage, icon: 'person' },
{ title: 'Logout', component: TutorialPage, icon: 'log-out' }
];
this.loggedOutPages = [
{ title: 'Login', component: LoginPage, icon: 'log-in' },
{ title: 'Signup', component: SignupPage, icon: 'person-add' }
];
// decide which menu items should be hidden by current login status stored in local storage
//alert('about to check hasLoggedIn');
this.userData.hasLoggedIn().then((hasLoggedIn) => {
this.loggedIn = (hasLoggedIn == 'true');
//alert('logged in = '+this.loggedIn);
// If logged in show VeeU page else show tutorial page
if (this.loggedIn) {
// Setup user ID global
this.userData.veeuID().then((veeuID) => {
this.root = VeeUPage;
});
}
else {
this.root = TutorialPage;
}
});
this.listenToLoginEvents();
}
// Called by menu items to open the appropriate page
openPage(page) {
this.menu.swipeEnable(true);
// find the nav component and set what the root page should be
// reset the nav to remove previous pages and only have this page
// we wouldn't want the back button to show in this scenario
//let nav = this.app.getComponent('nav');
if (page.index) {
this.nav.setRoot(page.component, {tabIndex: page.index});
} else {
this.nav.setRoot(page.component);
}
if (page.title === 'Logout') {
// Give the menu time to close before changing to logged out
setTimeout(() => {
this.userData.logout();
}, 1000);
}
}
listenToLoginEvents() {
this.events.subscribe('user:login', () => {
//alert("app.js:[user:login");
//alert("Login event handler");
this.loggedIn = true;
//let nav = this.app.getComponent('nav');
this.enableMenu(true);
//this.nav.setRoot(VeeUPage);
});
this.events.subscribe('user:signup', () => {
//alert("app.js:[user:signup");
// At the moment this event is not used as signup always calls login which creates the user:login event
this.loggedIn = true;
//let nav = this.app.getComponent('nav');
this.enableMenu(true);
//this.nav.setRoot(ProfilePage);
});
this.events.subscribe('user:logout', () => {
//alert("Logout event handler");
this.loggedIn = false;
this.enableMenu(false);
//let nav = this.app.getComponent('nav');
this.nav.setRoot(TutorialPage);
});
}
enableMenu(loggedIn) {
this.menu.enable(loggedIn, "loggedInMenu");
this.menu.enable(!loggedIn, "loggedOutMenu");
}
}
ionicBootstrap(ConferenceApp, [ConferenceData, UserData, MediaItemData], {
platforms: {
android: {
tabbarLayout: 'icon-hide'
}
}
});