0

I want to display the username on my NavbarComponent, the data coming from LoginComponent.

login.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder,FormGroup,Validators,FormControl } from '@angular/forms';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {


  form : FormGroup;
  message;
  messageClass;

  constructor(
    private formBuilder: FormBuilder,
    private authService:AuthService,
    private router: Router,
    private flashMessagesService:FlashMessagesService
    ) { 
    this.createForm();
  }


  createForm(){
    this.form=this.formBuilder.group({
      username:['', Validators.required],
      password:['', Validators.required]
    })
  }

  onLoginSubmit(){

    const user={
      username: this.form.get('username').value,
      password: this.form.get('password').value
    }

    this.authService.login(user).subscribe(data=>{
      if(!data.success){
        this.messageClass="alert alert-danger";
        this.message=data.message;
      }
      else{
        this.messageClass="alert alert-success";
        this.message=data.message;
        this.authService.storeUserData(data.token,data.user);
        setTimeout(()=>{
          this.router.navigate(['/profile']);
        },2000);

        this.flashMessagesService.show('Welcome to bloggy, '+ this.form.get('username').value +' !',{cssClass: 'alert-info'});

      }
    });
  }

}

navbar.component.ts

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';


@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {


  usernameNav;

  constructor(
    private authService:AuthService,
    private router:Router,
    private flashMessagesService:FlashMessagesService
    ) { }  



  onLogoutClick(){
    this.authService.logout();
    this.flashMessagesService.show('You are logged out',{cssClass: 'alert-info'});
    this.router.navigate(['/']);
  }


  ngOnInit() {

  }

}

I am sorry if there's too much code but basically i want to take data.user.username from LoginComponent in the onLoginSubmit() function, send it to NavbarComponent, use it in a variable and display it on the html. I tried to import the NavbarComponent, didn't work.

Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
Azoulay Jason
  • 2,787
  • 5
  • 21
  • 46
  • 2
    You should take a look at this: https://angular.io/guide/component-interaction especialy the last one, you're probably looking for service communication. – Ploppy Aug 08 '17 at 23:23
  • 1
    Look here as well: https://angular.io/tutorial/toh-pt4#services – LarsMonty Aug 08 '17 at 23:26
  • Hey thanks for your answers, you're both probably right, but it seems to me that creating a service only for one purpose is kinda weird. There must be a simpler way ! Anyway i'll check it out for now – Azoulay Jason Aug 08 '17 at 23:34
  • Is there any child-parent relationship between those two components? – asmmahmud Aug 09 '17 at 00:29

1 Answers1

1

Pretty Interesting question , basically solution to your problem is Observable/subscriber, you need to listen when the value changes in the login component and send it back to navbar component to display.

you can use global Observable like this

let suppose you create one Observable in your global file like this

public loggedInObs: Rx.Subject<any> = new Rx.Subject<any>();
public loggedInVar: boolean = false;

for using this you have to import some dependency like this

import { Observable } from 'rxjs/Rx';
import * as Rx from 'rxjs/Rx';
import 'rxjs/add/observable/of';
import 'rxjs/Rx';
import 'rxjs/add/operator/map';

Than in your login component you tell angular that there are some changes occurred like user login successfully. and fire observable , so that angular will able to listen in whole app where you set subscriber to listen that user have logged in into app. code for this as below

this.authService.login(user).subscribe(data=>{
  if(!data.success){
    this.messageClass="alert alert-danger";
    this.message=data.message;
  }
  else{
    this.messageClass="alert alert-success";
    this.message=data.message;

    localStorage.setItem('user_info', JSON.stringify(data.user))
    /*for Global level observable fire here*/
    this.global_service.loggedInVar = true;         //i assume global_service here as your Global service where we declared variables
    this.global_service.loggedInObs.next(this.global_service.loggedInVar);

    this.authService.storeUserData(data.token,data.user);
    setTimeout(()=>{
      this.router.navigate(['/profile']);
    },2000);

    this.flashMessagesService.show('Welcome to bloggy, '+ this.form.get('username').value +' !',{cssClass: 'alert-info'});

  }

now you can listen to this using subscriber everywhere in the app like this in your navbar component

userdata = JSON.parse(localStorage.getItem('user_info'));  // in case of normal loading page
this.userName = userdata.user_name

this.global_service.loggedInObs.subscribe(res => {       // in case of when without refresh of page
    console.log('changes here in login');
    userdata = JSON.parse(localStorage.getItem('user_info'));
    this.userName = userdata.user_name
})

if any doubt let me know.

Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215