How to Communicate between 2 Direct Child Components of AppComponent via Shared Service in Angular?

141 Views Asked by At

So I have read, but not found a solution to my problem. My question is as my title asks.

Here is my issue, I have created 2 components (NavbarComponent and HomepageComponent). NarbarComponent is nested in AppComponent and handles the authentication while HomepageComponent is a route enabled component and default page of the app.

What I want to do is be able to use an authentication service like Auth0 to authenticate a user by clicking the Login button in the nav-bar (NavbarComponent) and then render his/her profile on the homepage (HomepageComponent). Vice-versa, when I click the Logout button, the user's profile content should be removed.

I tried configure a few architecture, but to no avail. First, I tried NavbarComponent to HomepageComponent with the shared Service, but it only updates the HomepageComponent when the page is reloaded.

I tried using a shared service between the AppComponent and the NavbarComponent and then using @Input() to transmit from Parent to Child, HomepageComponent.

Then I tried @Output() and EventEmitter from NavbarComponent to AppComponent while running the shared Service between the AppComponent and HomepageComponent.

Any information or insight would greatly be appreciated!!

UPDATED

HomepageComponent

import { Component, OnInit } from '@angular/core'
import { Authenticated } from '../definitions/authenticated'
import { AuthCheckService } from '../shared/auth-check.service'

@Component({
  selector: 'afn-homepage',
  templateUrl: './homepage.component.html'
})
export class HomepageComponent implements OnInit{

  private authenticated: Authenticated;
  isAuthenticated: boolean;
  profile: any;

  constructor(public authCheckService: AuthCheckService) { }

  ngOnInit() {
    this.authCheckService.getAuthenticated().subscribe(authenticated => {
      console.log('Receiving auth info in home component from navbar component');
      this.authenticated = authenticated;
      this.isAuthenticated = this.authenticated.isAuthenticated;
      this.profile = this.authenticated.profile;
    });
  }

}

I tried making a plunker here. I wasn't able to get it to load, but it does have most of the code and a mock of AuthService.

2

There are 2 best solutions below

0
Sundar On

I guess what you want is something that works in this app.. https://angularhunt.com

Please check out the sourcecode at https://github.com/aviabird/angularhunt. Its been built on top of Angularfire2 with Redux(ngrx/store) for state management. So yo would need to understand the redux workflow first. If you already know that, then this should be a great reference. I will see if I could pull up a one without the redux way.

3
Yakov Fain On

You need to inject a service into both navbar and home components. When the user clicks on the Login button on the navbar, invoke a setter on the service that will do three things:

  1. perform the authentication
  2. store the user's credentials in a class variable (e.g. user) of the service
  3. using EventEmitter, emit an event that carries the user object

Also, define a getter in the service that will return the value of the variable user.

The home component gets the same service instance injected in the constructor. Subscribe to the service's emitter to get notifications when the user logs out or logs back in again. In the method ngOnInit, invoke the getter on the service to get the value of the user. Then make an http request to get the user's profile data.