JosephHuang
JosephHuang

Reputation: 41

Angular 13: Uncaught ReferenceError: Cannot access '' before initialization

I'm having an issue while developing Angular.

The code looks fine in the compiler (IntelliJ), but I encounter some problems when running it on the web page.

I have a QueryUser object that inherits from the BaseRequest object. It works fine within the component, but when I try to instantiate QueryUser inside a service, I get the error message "Uncaught ReferenceError: Cannot access '' before initialization" when opening the web page.

Environment:

Angular: 13.1.3

Node: 16.17.1

UserComponent.ts

@Component({
  selector: 'app-user-info',
  templateUrl: './user-info.component.html',
  styleUrls: ['./user-info.component.css']
})
export class UserComponent implements OnInit {
  constructor(
    private userService: UserService,
  ) {
  }

  ngOnInit(): void {
    this.generateInfo().then();
  }

  private async generateInfo(): Promise<void> {
    await this.userService.queryUserInfo(this.createRequest()).
        then()
  }

  private createRequest(): QueryUser {
    return new QueryUser();
  }
}

ToastService.ts

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

  constructor(
    private toastrService: ToastrService,
    private router: Router,
    private translate: TranslateService,
    private userService: UserService,
  ) {
  }

  toasts: any[] = [];

  async handleReminder(): Promise<void> {
    const userResponse: QueryUserResponse = await this.userService.queryUserInfo(this.createRequest());
    if (!userResponse.isValid) {
      // some logic
    }
  }

  private createRequest(): QueryUser {
    return new QueryUser();
  }
}

QueryUser.ts (Not Work)

export class QueryUser implements BaseRequest {
  accessToken: string;
  httpMethod: number;
  timeStamp: number;

  constructor() {
    this.accessToken = getAccessToken();
    this.httpMethod = OperationType.GET;
    this.timeStamp = Math.round(convertMilliSecondToSecond(new Date().valueOf()));
  }

  url(): string {
    return UrlUtil.transObjectToParameter(UnAuthenticatedApi.GET_USER, this);
  }
}

BaseRequest.ts

export class BaseRequest {
  accessToken: string;
  httpMethod: number;
  timeStamp: number;

  constructor(httpMethod: number) {
    this.accessToken = getAccessToken();
    this.httpMethod = httpMethod;
    this.timeStamp = Math.round(convertMilliSecondToSecond(new Date().valueOf()));
  }

  url(): string {
    return "";
  }
}

Assuming I change QueryUser to implement BaseRequest, the web page operated without any errors.

QueryUser.ts (Work)

export class QueryUser extends BaseRequest {
  constructor() {
    super(OperationType.GET);
  }

  override url(): string {
    return UrlUtil.transObjectToParameter(AuthenticatedApi.GET_USER, this);
  }
}

Upvotes: 2

Views: 4119

Answers (2)

Nick Johnson
Nick Johnson

Reputation: 1

Imports referencing index.ts in same directory

I had a similar issue to Timothy Matthews' answer here.

• Uncaught ReferenceError: Cannot access main. js: 426358
'Child1Component' before initialization at ‹static initializer> (main.is:426358:225)

Browser console error stack trace screenshot

Cause

Example file structure:

/parent.component.ts
/child1/child1.component
/child2/child2.component
/index.ts (exports all the above)

My IDE (intellij) set the imports in parent.component.ts to point at the index.ts in the same directory which also contains the child components, which causes the issue:

import {
  ChildComponent1,
  ChildComponent2,
} from '../';

Fix

I updated my imports to this, which fixed the issue:

import { ChildComponent1 } from '../child1/child1.component';
import { ChildComponent2 } from '../child2/child2.component';

Timothy Matthews notes above that this would also work, but I cannot confirm:

Change index.ts to _index.ts

import {
  ChildComponent1,
  ChildComponent2,
} from '../_index';

Upvotes: 0

Acker Apple
Acker Apple

Reputation: 495

Often the issue is circular dependencies, ya know, imports that import a file that eventually through some import re-imports the original file.

You typically just need to move exports around into isolated files.

To reveal circular dependencies, use the following magical cli command:

npx madge --circular --extensions ts ./

Upvotes: 8

Related Questions