Vishal Singh
Vishal Singh

Reputation: 585

Dynamically Update Side Menu in Ionic 2

I have a side menu in ionic 2 which I am trying to update after user logs in. I am using Events from ionic-angular. Here is what I have done.

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { Platform, Nav, AlertController, MenuController, Events } from 'ionic-angular';
import { HomePage } from '../pages/home/home';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {

  rootPage:any = HomePage;
  logoutAlert:any;
  currentUser:any;

  @ViewChild('nav') nav: Nav;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, public storage: Storage, public alertCtrl: AlertController, public menuCtrl: MenuController, public events: Events) {

    this.currentUser = {
      name: "Guest",
      username: "not logged in"
    };

    this.logoutAlert = this.alertCtrl.create({
      message: "Sure you want to log out?",
      buttons: [{text: "Yes", handler: () => {
        this.logoutUser();
      }}, {text:"No", role: "cancel"}]
    });

    this.menuCtrl.enable(false);

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

  ionViewWillLoad() {

    this.events.subscribe("userloggedin", (user) => {
        this.currentUser = JSON.parse(user);
    });

  }

app.html

<ion-menu [content]="content">
    <ion-item>
        <ion-avatar>
            <img src="../assets/letters/{{currentUser.name}}.svg">
        </ion-avatar>
        <p>
            {{currentUser.username}}
        </p>
    </ion-item>
</ion-menu>

<ion-nav id="nav" [root]="rootPage" #content></ion-nav>

home.ts

import { Component, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { NavController, Slides, LoadingController, Events } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { HttpProvider } from '../../providers/http/http';
import { TabsPage } from '../tabs/tabs';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

    @ViewChild('signSlides') signSlides: Slides;

    currentUser: any;
    loading:any;
    signinForm:any;

  constructor(public navCtrl: NavController,public formBuilder: FormBuilder, public storage: Storage, public httpProvider: HttpProvider, public loadingCtrl: LoadingController, public events: Events) {
    this.signinForm = formBuilder.group({
        email: [''],
        password: ['']
    });

    this.loading = this.loadingCtrl.create({
        content: "<ion-spinner></ion-spinner>"
    });
  }

  signinUser() {
    let params = {
        username: this.signinForm.value.email,
        password: this.signinForm.value.password
    };
    this.httpProvider.loginUser(params).subscribe(
        results => {
            this.loading.present();
            this.currentUser = results['_body'];
        },

        err => {
            alert("Oops! An error occured!");
        },
        () => {
            this.storage.set("currentUser", this.currentUser);
            this.loading.dismiss();
            this.navCtrl.setRoot(TabsPage);
        }
    );
  }

    this.httpProvider.registerUser(params).subscribe(
        results => {
            this.loading.present();
            this.currentUser = results['_body'];
        },
        err => {
            alert("Oops! An error occured!");
        },
        () => {
            this.storage.set("currentUser", this.currentUser);
        this.events.publish("userloggedin", this.currentUser);
            this.loading.dismiss();
            this.navCtrl.setRoot(TabsPage);
        }
    );

  }

  firstLetter(s:string) {
    s = s.toLowerCase();
    return s.charAt(0);
  }

}

I have tried putting events.subscribe in ionViewDidLoad, ionViewDidEnter and ngOnInit but nothing has worked for me. The data from home.ts is being saved in the storage but I can't figure out why doesn't it upadte in the ionic menu.

Upvotes: 1

Views: 4403

Answers (2)

Lucas Moulin
Lucas Moulin

Reputation: 2550

The app.component doesn't have the same callbacks as other pages, so you have to move your code to the class constructor:

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  constructor(private events: Events) {
    this.events.subscribe("userloggedin", (user) => this.currentUser = user);
  }
}

You don't need the JSON.parse(user) since Events doesn't convert the object to string.  

Upvotes: 2

DEEPAN KUMAR
DEEPAN KUMAR

Reputation: 174

It is suggested to pass a string value to the event, instead of a Json object, this.events.publish("userloggedin", this.currentUser);` If this.currentUser is a string in the above piece of code in your home.ts, then it should work as you expect. And also in app.component.ts,inside the constructor, you may put your code in this way.

this.events.subscribe("userloggedin", (user) => {
    this.currentUser = user
});

Upvotes: 4

Related Questions