Creating a redirect feature within an Angular application may lead to a null injection issue

My goal is to develop an Angular (version 11.2.9) routing service that will facilitate automatic redirection of users from one page to another within the site.

For instance, a guest user visiting the site can log in to their account by clicking on a button that directs them to the "Log in page." Once logged in, the button disappears, but the user can still access the login page by entering "/login" in the address bar. I want to set up automatic redirection from "/login" and similar pages to specific predetermined sites.

Here's a snippet from prijava.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from '../../services/authentication.service';
import { RedirectService } from '../../services/redirect.service';

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

export class LoginComponent implements OnInit {

public href: string = "";

constructor(
private router: Router,
private authService: AuthenticationService,
private redirectService: RedirectService,
) {}

/*Other variables, etc. Sending the data*/

ngOnInit() {
this.redirectService.redirectUnwanted();
 }

}

The redirect service being developed:

redirect.service.ts:

import { Router} from '@angular/router';
import {AuthenticationService} from './authentication.service';

export class RedirectService {

constructor(
 private router: Router,
 private authService: AuthenticationService

) { }

//Redirect unwanted sites
public redirectUnwanted(): void{

  //Check if user is logged in
  if(this.authService.isLoggedIn()){

  //Redirect from /login, /registration, /passwordRecovery

    console.log(this.router.url); 
   }
  }
}

When clicking on a routerLink with '/login', an empty page is displayed along with the following error message:

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[RedirectService -> RedirectService -> RedirectService]:

NullInjectorError: No provider for RedirectService! ... (error continues)

I have tried various solutions such as adding a 'providers' field in the @Component declaration of the login component, but it resulted in a different error about not having an Angular decorator.

In addition, attempts to use an AuthGuard implementing CanActivate also led to errors regarding property assignment and type mismatch.

Alternatively, there is a history service available. Is there any way to utilize or improve upon the functionality provided by this service?

history.service.ts:

import { Injectable } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HistoryService {

      private urlAddresses: string[] = [];

      constructor(private router: Router) {
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: NavigationEnd) => {
        const url = event.urlAfterRedirects;
        this.urlAddresses = [...this.urlAddresses, url];
      })
      }

      public getPreviousUrl(): string {
        const length = this.urlAddresses.length;
        return length > 1 ? this.urlAddresses[length - 2] : '/';
           }
         
      public getPreviousUrlExcludingSelected(): string {
        const exclude: string[] = ['/register', '/login', '/forgotPassword','/resetPassword/:email', 
    '/users/:userId', ];
        const filtered = this.urlAddresses.filter(url => !exclude.includes(url));
        const length = filtered.length;
        return length > 1 ? filtered[length - 1] : '/';
      }

    }

In conclusion, what is the correct approach to implement a robust and error-free redirection service within an Angular application?

Answer №1

If you find yourself needing to send the user to a different path besides /login in certain situations, such as redirecting them from the login page if they are already logged in, consider implementing a route guard for that specific route. You can learn more about route guards and how to use them here: https://angular.io/api/router/CanActivate

A route guard allows you to return a URL tree to specify where to redirect the user, or you can simply return true to allow the user access to the login page if they are not already logged in.

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

AG Grid, efficiently organizing hierarchical data with tree structures and allowing filtering at all levels, not just leaf

My grid is receiving tree formatted data, and I've noticed that when using column filters, they apply to the leaf nodes as well as show parent nodes necessary to provide a path to the leaves. I'm interested in finding a method to allow users to ...

Tips for accurately specifying types for TypeScript map, reduce, filter, and other functions

Encountering errors in my TS code when attempting to provide the correct type to the built-in .map and .filter functions. For example, using: Object.values(league.games).map((game: Game) => { results in Error: Argument of type '(game: Game) => ...

What steps can be taken to address TypeScript error TS2339: Property 'XXX' is not present on type 'IntrinsicAttributes & ...?

Currently in my typescript/reactjs application, I am attempting to pass a property named 'test' like so in the index.tsx file: ReactDOM.render( <Provider store={getStore()}> <BrowserRouter> <App test={1} /> < ...

Is it possible to generate a dynamic Nextjs route with the format [id]-[first_name]-[last_name]?

In my Next.js project, I am working on creating a directory feature. My goal is to have an 'info' page load when clicking on the 'more info' button, with the URL structure of /info/[id]-[first_name]-[last_name]. The data is fetched from ...

Setting an expiration date using the HSET function in a Node.js application with TypeScript and Redis

When setting up caching in a Node express app with typescript, I attempted to store data using the HSET function. However, it is necessary for the stored data to expire after a certain amount of time. Below is how I implemented the HSET function. Since I a ...

Angular 5 Custom validators: Error message - 'passwordG' is not defined in ng

Currently working with Angular 5 and attempting to create custom validators for password inputs along with a confirmation password field. This is the HTML code : <div formGroupName = "passwordG"> <div class="form-group"> <label ...

Steps for stopping TypeScript compiler's watch mode

While working on the Angular quickstart tutorial, I've noticed that my browser automatically refreshes whenever I make a change, even without saving. This unnecessary auto-refresh puts extra strain on my computer, as I prefer to manually refresh when ...

The error message states that the type '{}' does not contain the property 'API_BASE_URL'

Encountering this error message when trying to access my API_URL as defined in the enviroment.ts file within a service class. Error: src/app/product/product.service.ts:12:25 - error TS2339: Property 'API_BASE_URL' does not exist on type '{} ...

Tips for correctly implementing an authorize function in TypeScript with NextAuth.js

Trying to implement the Credentials Provider in NextJs ("next": "^12.0.7") and NextAuth ("next-auth": "^4.1.2") using TypeScript has been a challenge. I am encountering difficulties in getting the function to work co ...

React-leaflet with TypeScript is failing to display GeoJSON Points on the map

I am attempting to display points on a map using geojson points in my react application with react-leaflet. However, for some unknown reason, the points are not rendering on the map. When I try importing a JSON file, I encounter an error: TS2322: Ty ...

ngFor displaying an abundance of elements

I am retrieving data from a database and utilizing an ngFor loop to display it. Here is the HTML code snippet: <div style="background:black; color:aliceblue;" class="col-md-8 col-md-offset-2 text-center" [routerLink]="['todo']"> ...

Is there a way to utilize the 'interval' Rxjs function without triggering the Change Detection routine?

My goal is to display the live server time in my application. To achieve this, I created a component that utilizes the RXJS 'interval' function to update the time every second. However, this approach triggers the Change Detection routine every se ...

Table with expandable rows in Angular 5

Currently, I'm developing an application using Angular 5 that requires me to create a table with a drill-down feature. This table will have multiple parent-child components, and when a parent is clicked, all its children should be displayed in a drill ...

Exploring the versatility of Highcharts with callback functions and comprehensive

Currently, I am utilizing Highcharts with angular 9. Here is the link to the code : https://stackblitz.com/edit/angular-ivy-wdejxk For running on the application side or test side, follow these instructions: Test Side: In the angular.json file at line ...

Is it possible to merge these two scripts into a single one within Vue?

As a newcomer to VUE, I am faced with the task of modifying some existing code. Here is my dilemma: Within a single component, there are two script tags present. One of them contains an import for useStore from the vuex library. The other script tag incl ...

How about integrating Angular with Firebase and Node JS?

At the moment, I am utilizing Angular in conjunction with Firebase for authentication and data storage. My goal is to send emails to users directly through Angular. However, I came across a method that involves using Node.js to send emails. Is it feasibl ...

The following error has occurred: TypeError - It is not possible to call the class constructor EventEmitter_ without using the keyword 'new

Since upgrading to Angular 10, I've encountered a specific error with some components: ERROR TypeError: Class constructor EventEmitter_ cannot be invoked without 'new' at new ZoneAwareEventEmitter (index.js:34) at new GridComponent ( ...

The property 'fullName' is assumed to have type 'any' due to the missing parameter type annotation in its set accessor

While enrolled in a JS course, I encountered the following code that was not functioning properly when added. Instead of returning the expected result, it returned 'undefined.' After investigating further, I identified that the issue lies within ...

Setting up Prettier for automatic code formatting with Eslint: A step-by-step guide

To streamline our development process and focus on writing quality code, we are configuring our Angular project using ESLint and Prettier. By following the guidelines outlined in https://github.com/angular-eslint/angular-eslint#notes-for-eslint-plugin-pret ...

The hide function of the NgxSpinner does not seem to be working properly

Lately I've been incorporating NgxSpinner into my projects, but I've encountered a peculiar issue with the spinner.hide() function. I want to trigger this function within the subscribe complete function because that's the ideal moment for it ...