Conceal certain components when a user is authenticated

Below is the content of my app.component.html:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class='container'>
    <ul class="nav navbar-nav">
      <li class='nav-item'>
        <a class='nav-link' routerLink="/">Home</a>
      </li>
      <li class='nav-item'>
        <a class='nav-link' routerLink="/about">About</a>
      </li>
      <li class='nav-item' *ngIf='!user'>
        <a class='nav-link' routerLink="/login">Login</a>
      </li>
      <li class='nav-item' *ngIf='!user'>
        <a class='nav-link' routerLink="/register">Register</a>
      </li>
      <li class='nav-item' *ngIf='user'>
        <a class='nav-link' routerLink="/logout">Logout</a>
      </li>
    </ul>
  </div>
</nav>
<main>
  <router-outlet></router-outlet>
</main>

I am attempting to display the /logout button when the user is logged in, and hide it otherwise. Similarly, I want to show the /login and /register buttons if the user is not logged in.

This is how my login logic looks:

import {Component} from '@angular/core';
import {AuthService} from '../core/auth.service';
import {Router, Params} from '@angular/router';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'page-login',
  templateUrl: 'login.component.html',
  styleUrls: ['login.scss']
})

export class LoginComponent {
  loginForm: FormGroup;
  errorMessage: string = '';

  constructor(
    public authService: AuthService,
    private router: Router,
    private fb: FormBuilder
  ) {
    this.createForm();
  }

  createForm() {
    this.loginForm = this.fb.group({
      email: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  tryFacebookLogin() {
    this.authService.doFacebookLogin()
      .then(res => {
        this.router.navigate(['/user']);
      });
  }

  tryTwitterLogin() {
    this.authService.doTwitterLogin()
      .then(res => {
        this.router.navigate(['/user']);
      });
  }

  tryGoogleLogin() {
    this.authService.doGoogleLogin()
      .then(res => {
        this.router.navigate(['/user']);
      });
  }

  tryLogin(value) {
    this.authService.doLogin(value)
      .then(res => {
        this.router.navigate(['/user']);
      }, err => {
        console.log(err);
        this.errorMessage = err.message;
      });
  }
}

An example of the doLogin function is provided below:

doLogin(value){
  return new Promise<any>((resolve, reject) => {
    firebase.auth().signInWithEmailAndPassword(value.email, value.password)
    .then(res => {
      resolve(res);
    }, err => reject(err))
  })
}

I come from an Express background and I'm relatively new to Angular. In Express, I would typically use a session variable to track whether a user is logged in or not. How can I achieve something similar in Angular?

Answer №1

When using Firebase, you can utilize the authentication object provided by the library. Simply save the connection result into a variable for easy display.

import * as firebase from 'firebase/app';

randomFunction() {
  firebase.auth().onAuthStateChanged(user => {
    if(user) {
      this.logged = true;
    } else {
      this.logged = false;
    }
  });
}

In your HTML

<div *ngIf="logged; else #isAnonymous">
  <button>Log out</button>
</div>
<ng-template #isAnonymous>
  <button>Log in</button>
</ng-template>

Answer №2

Upon further discussion in the comments of the accepted answer, it was determined that implementing a LocalStorage strategy to verify user login status would be beneficial.

To streamline the authentication process, I recommend creating a dedicated service:

auth.service.ts

import { LocalStorageService } from 'angular-2-local-storage';

@Injectable()
export class AuthService {

  constructor(private http: Http, private localStorage: LocalStorageService) { }

  login(email: string, password: string): Observable<any>{
    // Perform necessary actions;
    // Set to LocalStorage upon successful login
}

  isAuthenticated(): boolean{
    if (this.localStorage.get('isLoggedIn')){
      return true;
    }
    else{
      return false;
    }
  }

}

With this service in place, any component can easily utilize it by injecting and calling as shown below:

your.component.ts

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

  constructor(private authService: AuthService) { }
  let isLoggedIn = false;    

  ngOnInit() {
    isLoggedIn  = this.authService.isAuthenticated();

    if (isLoggedIn){
      alert('hello');
    }
  }

You can now use the isLoggedIn variable in your template with the *ngIf directive

Answer №3

To ensure user authentication, create a variable called isLoggedIn at the component level (or utilize LocalStorage to store and access it throughout the application). Upon successful authentication of the user, toggle this variable between true and false.

Utilize *ngIf directive at the component level to show or hide specific content based on the user's login status.

Answer №4

To keep track of the user's login status in your component, you can create a variable for it. When navigating to the /user route, remember to set this.isAuthenticated= true as shown below.

When logging out, ensure that you update this variable to false.

this.isAuthenticated = false;

Below is an example of how the component code might look like:

import {Component} from '@angular/core';
import {AuthService} from '../core/auth.service';
import {Router, Params} from '@angular/router';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'page-login',
  templateUrl: 'login.component.html',
  styleUrls: ['login.scss']
})

export class LoginComponent {
  isAuthenticated:boolean = false;
  loginForm: FormGroup;
  errorMessage: string = '';

  constructor(
    public authService: AuthService,
    private router: Router,
    private fb: FormBuilder
  ) {
    this.createForm();
  }

  createForm() {
    this.loginForm = this.fb.group({
      email: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  tryFacebookLogin() {
    this.authService.doFacebookLogin()
      .then(res => {
        this.isAuthenticated = true;
        this.router.navigate(['/user']);
      });
  }

  tryTwitterLogin() {
    this.authService.doTwitterLogin()
      .then(res => {
      this.isAuthenticated = true;
        this.router.navigate(['/user']);
      });
  }

  tryGoogleLogin() {
    this.authService.doGoogleLogin()
      .then(res => {
      this.isAuthenticated = true;
        this.router.navigate(['/user']);
      });
  }

  tryLogin(value) {
    this.authService.doLogin(value)
      .then(res => {
        this.isAuthenticated = true;
        this.router.navigate(['/user']);
      }, err => {
        this.isAuthenticated = false;
        console.log(err);
        this.errorMessage = err.message;
      });
  }

  logOut(){
    //write logout logic from server here
    this.isAuthenticated = false;
  }
}

On your template, you can display different buttons based on the authentication status:

<div *ngIf="isAuthenticated>Show Logout button</div>
<div *ngIf="!isAuthenticated">Show Login button</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Triggering an Ajax call for form validation only occurs when the form is not validated

I am struggling with a simple form that has an Ajax call, but the ajax call gets executed even if the form is not validated. In the code snippet below, the line console.log("This line should execute only if Form is validated"); gets executed when the form ...

Identifying Oversized Files on Safari Mobile: A Guide to Detecting Ignored Large Files in

Mobile browsers such as Safari have a tendency to ignore large files when passed in through the <input type="file">. For example, testing with a 10mb image file results in no trigger of any events - no change, no error, nothing. The user action is si ...

Tips on showing content while filtering is taking longer with AngularJS

When working in Angular, I encountered a situation where filtering a large amount of data in a table was slowing down the process. To address this issue, I wanted to display a spinner every time a filter operation was in progress. Here is an example simil ...

Using Vue: Triggering .focus() on a button click

My journey with vue.js programming started just yesterday, and I'm facing a challenge in setting the focus on a textbox without using the conventional JavaScript method of document.getElementById('myTextBox').focus(). The scenario is that i ...

Utilize Element-UI to effectively close dropdown menus

In my Vue application with ElementUI, I have a drop down menu that needs to be explicitly closed after some logic is applied. The process is as follows: User loads the page, selects a name from the drop-down - the name value is saved in the database User ...

Steps to resolve the issue: The current experimental syntax 'classProperties' is not supported

I encountered an issue where the experimental syntax 'classProperties' is not supported when trying to run my react js application. My goal is to increment the value inside a <span> when a ` button is clicked. Below is the excerpt of my c ...

Transforming an interactive HTML webpage into React/JSX

Imagine a scenario where I have two files: example.html <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="u ...

Transforming a PHP cURL call to node.js

Currently exploring the possibility of utilizing the Smmry API, however, it seems that they only provide PHP API connection examples. Is there anyone who could assist me in adapting it into a JS request? My requirement is simple - I just need it to analyz ...

Vue appears to be having trouble waiting for the axios Post request

While testing a login request, I encountered an issue where jest did not call the mock: This is my test : const User = '123123' jest.mock('axios', () => ({ get: jest.fn(), post: (_url, _body) => new Promise((resolve, reject ...

Can we find a method to incorporate multicolored borders?

I currently have a td element with the following CSS styling: td { border-bottom: 3px solid aqua; } I want to be able to click on these cells and change their color, similar to the images linked below: Is there a way to achieve multi-color borders fo ...

Is there a way to prevent a .load() function from executing if it has

On my webpage, I have implemented multiple buttons that each load a different partial "view" using the jQuery .load() method. While this functionality works well, I observed that repeatedly clicking on one specific button results in the partial view being ...

Implementing real-time database updates in FullCalendar Angular when events are dragged and resized

I have integrated fullcalendar into my Angular project and successfully retrieved data from my API to display events: @Component({ selector: 'app-installboard', templateUrl: './installboard.component.html', styleUrls: ['./in ...

Issue with unrecognized expression in JQuery when processing Ajax response

Recently, I implemented a JQuery Ajax Form on my website. $('#modal-body-sign-in').on('submit', '#sign-in', function(e) { e.preventDefault(); var data = $(this).serialize(); var url = $(this).attr(&apo ...

The CSS and Javascript files are failing to load

My web page is not displaying my CSS and JavaScript properly when I access it through a folder in the browser. Both files are located within multiple subfolders. I have attempted to rename the files to troubleshoot the issue. <head> <link rel=" ...

Leverage the power of Bootstrap by incorporating not one, but two carousels on a single page - one featuring a single item per

I have a unique challenge with using multiple Bootstrap Carousels on my WordPress website One of the carousels features one item per slide, while the other carousel has three items per slide, moving one item at a time in a cyclical pattern like this: [1, ...

Is there a way to retrieve a raw value from the API response that matches the one shown in POSTMAN, but my attempts have been unsuccessful?

Looking for some assistance with fetching data from a front-end (React) to the raw value in JSON. Specifically, I'm having trouble with the login functionality. When I input my email and password, the response should match what I see in POSTMAN, but i ...

Unable to post form data into database due to Javascript undefined data situation

I've been working on an HTML form that can interact with a PHP API to retrieve client data and then update user stats in a MySQL database. Currently, I am converting the data into a JSON object and using JSON.stringify to create a string for sending ...

What is the best approach to perform a search in mongoose based on specific query parameters?

I have a form that allows users to search for transactions by specifying the buyer name, item name, or both. This means I can receive any of these queries: localhost:8000/allPayments/?i=pasta localhost:8000/allPayments/?b=Youssef localhost:8000/ ...

Modify the state of an individual item within an array

I have a list of items that I need to show a loader for and hide it once a certain action is completed. For instance, below is my array of items: [ { "id": "69f8f183-b057-4db5-8c87-3020168307c5", "loading": null } ...

Get rid of the .php extension in the URL completely

Lately, I've been experimenting a lot with the .php extension. I successfully used mod_rewrite (via .htaccess) to redirect from www.example.com/example.php to www.exmaple.com/example. Everything is running smoothly. However, I noticed that even though ...