Dynamically display items in menu

I am building an ionic app using AWS as a backend (has been challenging!), and for some reason on my user sign-in page, I got this nasty bug that wasn’t there when I was using firebase as the backend. In a nutshell, my side menu has items that should appear based on whether the user is logged in or not. If the user is logged in, the menu should have a logout item. If the user is not logged in, the menu should either not have any options, or a redundant sign-in option.

I got the hard part down, which was setting up AWS Cognito to work the sign-in logic, and setting the correct root page, however, after a user logs in, the menu does not show the logout option.

Funny thing, if I reload the app, the menu does show the logout option. Not sure why. Also weird, after I reload the app and I click the logout button, the correct options for a user that is not logged in do appear in the menu. If someone can take a look and tell me why the menu options only render correctly when I log out and if I log in only after I reload the app, I would be very grateful! Thank you in advance for your time! Code below…

app.component.ts:

import { Component } from ‘@angular/core’;
import { Platform, NavController, MenuController } from ‘ionic-angular’;
import { StatusBar } from ‘@ionic-native/status-bar’;
import { SplashScreen } from ‘@ionic-native/splash-screen’;

import { TabsPage } from ‘…/pages/tabs/tabs’;
import { SignInPage } from ‘…/pages/sign-in/sign-in’;
import { AuthService } from ‘…/services/auth’;

@Component({
templateUrl: ‘app.html’
})

export class MyApp {
rootPage: any;
isLoggedIn //this variable holds the status of the user and determines the menu items;

constructor(platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private menuCtrl: MenuController,
private authService: AuthService) {

this.verifyUserstate(); //method to check if a user is logged in
console.log(this.isLoggedIn); //debug line
console.log(this.menuCtrl.get()); //debug line

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.
  statusBar.styleDefault();
  splashScreen.hide();
});

}

onLoad(page: any) {
console.log(“onLoad”);
this.nav.setRoot(page);
this.menuCtrl.close();
}

onLogout() {
this.authService.logout();
this.verifyUserstate();
this.menuCtrl.close();
}

verifyUserstate() {
console.log(“in verify userstate”);
this.authService.isAuthenticated()
.then(() => {
this.isLoggedIn = true; //if a user is logged in = true
this.rootPage = TabsPage;
console.log(this.isLoggedIn); // more debug
})
.catch((error) => {
this.isLoggedIn = false; //if user is not logged in = false
this.rootPage = SignInPage;
console.log(this.isLoggedIn); //more debug
});
}
}
app.html:

<ion-menu [content]=“nav”>


Menu




<button ion-item icon-left (click)=“onLoad(signinPage)” *ngIf="!isLoggedIn">

Sign In

<button ion-item icon-left (click)=“onLogout()” *ngIf=“isLoggedIn”>

Log Out



auth.ts:

import { Injectable } from “@angular/core”;
import { AlertController } from “ionic-angular”;
import { CognitoUserPool, AuthenticationDetails, CognitoUser, CognitoUserSession } from “amazon-cognito-identity-js”;

const POOL_DATA = {
UserPoolId: “xx-xxxx-X_XXXX”,
ClientId: “You do not need to know :)”
}

const userPool = new CognitoUserPool(POOL_DATA);

export class AuthService {

signin(email: string, password: string) {
let message: string;
var authenticationData = {
Username : email,
Password : password,
};

var authDetails = new AuthenticationDetails(authenticationData);
let userData = {
    Username: email,
    Pool: userPool
}

let cognitoUser = new CognitoUser(userData);

return new Promise((resolve, reject) => {
    cognitoUser.authenticateUser(authDetails, {
        onSuccess(result: CognitoUserSession) {
            console.log(result)
            resolve("Success!")
        },
        onFailure(error) {
            let message: string = error.message;
            reject(message);
        }

}

logout() {
this.getAuthenticatedUser().signOut();
}

isAuthenticated() {
return new Promise((resolve, reject) => {
let user = this.getAuthenticatedUser();

    if (user) {
            user.getSession((err, session) => {
                if(session.isValid()) {
                    resolve(true);
                } else if (err) {
                    reject(err.message);
                }
            })
    } else {
        reject("Not authenticated");
    }
});

}
}

Finally, the sign-in.ts file (where the magic of login in happens):

import { Component } from ‘@angular/core’;
import { NgForm } from ‘@angular/forms’;
import { LoadingController, AlertController } from ‘ionic-angular’;

import { AuthService } from ‘…/…/services/auth’;
import { NavController } from ‘ionic-angular/navigation/nav-controller’;
import { MyApp } from ‘…/…/app/app.component’;

@Component({
selector: ‘page-sign-in’,
templateUrl: ‘sign-in.html’,
})
export class SignInPage {

constructor(private authService: AuthService,
private loadingCtrl: LoadingController,
private alertCtrl: AlertController,
private navCtrl: NavController) {
}

onSignin(form: NgForm) {
const loading = this.loadingCtrl.create({
content: “Signing you in…”
});
loading.present();

this.authService.signin(form.value.email, form.value.password)
.then(data => {
this.navCtrl.setRoot(MyApp); /*navigate to myApp again to reverify the
*login status. This sets the right rootPage,
*but I have a feeling here also lies the menu problem.
*/
console.log(data);
})
.catch(error => {
console.log(error);
let alert = this.alertCtrl.create({
title: “Oops”,
message: error,
buttons: [“Ok”]
});

  alert.present();
})
loading.dismiss();

}
}