0

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.

Andrew Lobban
  • 2,065
  • 2
  • 24
  • 38
  • The shared service should be the one to go. Could you create a plnkr with what you've tried with that approach and let people see what you've missed? – Harry Ninh May 28 '17 at 23:29
  • @HarryNinh Added plnkr per your request. I think I missed something when I added the AuthService as it no longer loads. – Andrew Lobban May 30 '17 at 17:00
  • Maybe a stupid question, but why don't you use different routes for this instead of squeezing all the different states into one component and then use Guards to handle the authentication and just reroute the user? – seBaka28 Jul 31 '19 at 12:56

2 Answers2

0

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.

Sundar
  • 41
  • 7
0

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.

Yakov Fain
  • 11,972
  • 5
  • 33
  • 38