Upon refreshing the page, an error occurred stating: 'ReferenceError: unable to access the lexical declaration 'BaseRepository' before initialization'

In my code, I have an abstract class called BaseRepository which includes a client instance and some general functions. The AuthRepository class inherits from the BaseRepository. Additionally, there is an AuthService module that utilizes the AuthRepository for login functionality and checking login status. When a route is opened, a request is sent to the API. The AuthService is used to obtain a token for authorization in the client request interceptor. If the token is successfully acquired, it is added to the headers and the request continues. Otherwise, the user is redirected to the login page to log in again. While this setup works without issue after the initial login, a "ReferenceError: can't access lexical declaration 'BaseRepository' before initialization" occurs when the page is refreshed.

BaseRepository

import { BackendClient } from "@/repositories/clients";
import type { AxiosError, AxiosInstance, AxiosResponse } from "axios";

// other imports

export default abstract class BaseRepository {
    protected readonly client: AxiosInstance = BackendClient;
    // general functions
}

AuthRepository

import { BaseRepository } from "@/repositories/base";

class AuthRepository extends BaseRepository {
    constructor() {
        super()
    }
    // other functions
}

const authRepository = new AuthRepository();

export default authRepository;

Axios client

import axios, { type AxiosInstance } from "axios";

import { AuthService } from "@/modules/auth";
import router from "@/router";

import appConfig from "@/config";

const client: AxiosInstance = axios.create({
  baseURL: appConfig.backendClient.baseUrl,
  headers: {
    "Access-Control-Allow-Origin": "*",
  },
  validateStatus: (status: number): boolean => {
    var isValid = (status < 400 || status == 401);
    console.log("requestvalidatestatus", isValid);
    return isValid;
  }
})

const TOKEN_EXCLUDE_ENDPOINTS = [
  'Auth/Login',
  'Auth/Register',
  'Auth/RefreshAccessToken'
]

client.interceptors.request.use(async (config) => {
  var requestUrl = config.url;
  for(var excludeEndpoint of TOKEN_EXCLUDE_ENDPOINTS) {
    if(requestUrl?.startsWith(excludeEndpoint)){
      return config;
    }
  }

  var token = await AuthService.getAccessToken();

  if(!token) {
    router.push('/login');
  }
  console.log("token",token);
  config.headers.Authorization = `Bearer ${token}`;
  return config;
})

export default client;

AuthService

import { AuthRepository } from "@/repositories";

class AuthService {
    async login(request: LoginRequest, rememberMe: boolean, forceLogin: boolean = false) {
        // other logic
        return await AuthRepository.login(request);
    }
    // other functions
}

const authService = new AuthService();

export default authService;

What could be causing this issue?

Answer №1

After encountering a circular dependency issue, I was able to resolve it by implementing a request interceptor in the main.ts file.

main.ts

import { BackendClient } from './repositories/clients'
import { AuthService } from './modules/auth'

const TOKEN_EXCLUDE_ENDPOINTS = [
    'Auth/Login',
    'Auth/Register',
    'Auth/RefreshAccessToken'
]

BackendClient.interceptors.request.use(async (config) => {
    var requestUrl = config.url;
    for (var excludeEndpoint of TOKEN_EXCLUDE_ENDPOINTS) { // Skip if endpoint does not require a token
        if (requestUrl?.startsWith(excludeEndpoint)) {
            return config;
        }
    }

    var token = await AuthService.getAccessToken();

    if (!token) {
        router.push('/login');
    }
    console.log("token", token);
    config.headers.Authorization = `Bearer ${token}`;
    return config;
})

BackendClient.ts

import axios, { type AxiosInstance } from "axios";

import appConfig from "@/config";

const client: AxiosInstance = axios.create({
  baseURL: appConfig.backendClient.baseUrl,
  headers: {
    "Access-Control-Allow-Origin": "*",
  },
  validateStatus: (status: number): boolean => {
    var isValid = (status < 400 || status == 401);
    console.log("requestvalidatestatus", isValid);
    return isValid;
  }
})

export default client;

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

The JSX component in next.js cannot be utilized as a user component

I am facing difficulty in getting my mobile menu to function properly. Initially, I attempted to position it above other content using the useEffect hook, but unfortunately, it resulted in breaking the entire project. This is the error message I encountere ...

Is there a way to subscribe to various observables simultaneously in Angular 2, and then pause until fresh data is available on each of them?

I have an Angular component that relies on 3 services, each of which has an observer I can subscribe to. The view of the component needs to be updated whenever there are changes in the observed data, which occurs through websockets (feathers.js). I want th ...

Palantir Forge: Enhancing Column Values with Typescript Functions

I am seeking assistance with a TypeScript function related to ontology objects. I want to develop a TypeScript program that accepts a dataframe as input. The objective is to nullify the values in other columns when a value from a row in a particular column ...

Issue: The system needs the 'image' property to proceed (Dall E's image variation API by OpenAI)

Utilizing the Dall E Create image variation API has been a bit challenging for me. Every time I send a post request, I encounter this particular error: error: { "code": null, "message": "'image' is a required property&q ...

Switching between components in vue.js: A beginner's guide

In my project, I created a Dashboard.vue page that consists of three child components: Display, sortBooksLowtoHigh, and sortBooksHightoLow. The Dashboard component also includes a select option with two choices: "Price: High to Low" and "Price: Low to High ...

Unexpected behavior with AWS DynamoDB ScanInput ExpressionAttributeValue

I crafted a scan query to only retrieve enabled data in the following way: const FilterExpression = 'enabled = :enabled'; const ExpressionAttributeValues = { ':enabled': { 'BOOL': true } }; const scanParameters: Sc ...

Having trouble displaying Vue Toast messages?

I have been trying to incorporate a toast message into my code, but unfortunately, the message does not appear and there are no errors in the console. The code functions properly and the invitation is sent successfully. I have used similar code in other fi ...

Create a small circle in the bottom left corner with a constrained size

I'm trying to create a circle at the top of the screen on mobile, similar to the image below. The circle should take up a percentage of space, with the rest of the content appearing against a blue background as shown in the image. However, I'm h ...

What is the best way to ensure an observable has finished before retrieving a value?

Looking at the function provided below: public getAssemblyTree(id: number) { .... const request = from(fetch(targetUrl.toString(), { headers: { 'responseType': 'json' }, method: 'GET' })); request.sub ...

Controlling CSS Styles in Angular using TypeScript

Currently, I am working on an Angular project that involves dynamically populating a calendar. In addition to this, I have a range of dates and the task at hand is to modify the background for specific days within this date range. To manage dates effective ...

Is it wrong to use <match v-for='match in matches' v-bind:match='match'></match>? Am I allowed to incorporate the match variable from the v-for loop into the v-bind attribute on the

I am attempting to display HTML for each individual match within the matches array. However, I am uncertain if <match v-for='match in matches' v-bind:match='match'></match> is the correct syntax to achieve this. To clarify, ...

What is the process of adding new fields to a model in TypeScript?

I have created a test.model.ts file: export interface ITransaction { description: string; transactionDate: string; isDebit: boolean; amount: number; debitAmount: string; creditAmount: string; } export class Transaction implements ...

How can I stop the setinterval function in JavaScript?

My issue revolves around intervals. Upon declaring a function with setInterval, I find that even after clearing the interval, the function continues to execute. Here is my code: if (score == 1) { leftBlinkTimer(0) } else if (score == 0) { leftBlin ...

Looping Through RxJS to Generate Observables

I am facing the challenge of creating Observables in a loop and waiting for all of them to be finished. for (let slaveslot of this.fromBusDeletedSlaveslots) { this.patchSlave({ Id: slaveslot.Id, ...

Retrieving data using ngxs selector for displaying nested JSON data

My issue is related to the user object that contains nested arrays, making it difficult to access secondary arrays. I have created selectors with ngxs to retrieve and utilize data in HTML code, but extracting secondary arrays seems impossible. { "us ...

Tips for iterating within a Vue.js template without disrupting the HTML structure

Currently, I am attempting to implement a loop within a table. However, I have encountered an issue with the following code: <tr v-for="( block , index ) in listRenderBlock" :key="index"> <div v-for="( section , i ) in ...

Navigate the nested route of a child page starting from the main Root component

I am facing an issue with enabling nesting routes on the BarcodeScannerComponent component. I have attempted the following method, but it does not seem to work. The main challenge lies in accessing the nested route within the root component, which is app.c ...

Error TS2307: Module 'bluebird' not located

Currently, my focus is on developing an app using Ionic 2 and Angular 2 along with Typescript. To incorporate messaging into my app, I opted to utilize the library amqp-ts. The installation of the library through npm was successful with the following comma ...

Tips for effectively incorporating customized validation into an array using vuelidate

My array of objects has a specific structure that looks like this varientSections: [ { type: "", values: [ { varientId: 0, individualValue: "" } ] } ] To ensure uniqueness, I implemented a c ...

Attempting to execute a synchronous delete operation in Angular 6 upon the browser closing event, specifically the beforeunload or unload event

Is there a way to update a flag in the database using a service call (Delete method) when the user closes the browser? I have tried detecting browser close actions using the onbeforeunload and onunload events, but asynchronous calls do not consistently wor ...