3

Just another day in the office, right? What once worked is no longer working. Yay!

I am supporting an Angular 8 web application and attempting to kickstart localhost:4200.

That said, the following error "Unable to find context associated with [object HTMLDivElement]" returns from Chrome DevTools after npm run start completes:

core.js file is: webpack:///./node_modules/@angular/core/fesm2015/core.js and kickstarting localhost uses aot (ahead of time compilation).

From Chrome DevTools:

enter image description here

I have tried multiple options (e.g. polyfill updates, assigning a new target to tsconfig.json, npm packages for custom elements, etc.) from these previous resources with no luck:

Subsequently, I've done some of the more known lifehacks to date, including:

  • Uninstall node_modules in the existing local project, then reinstall.
  • Pull down a new local repository and run npm install.
  • Uninstall everything on my operating system (NodeJS, Angular CLI), then reinstall.

package.json is as follows:

  "dependencies": {
    "@agm/core": "^1.0.0-beta.5",
    "@angular-devkit/build-angular": "^0.803.8",
    "@angular/animations": "8.2.9",
    "@angular/cdk": "8.2.2",
    "@angular/common": "8.2.9",
    "@angular/compiler": "8.2.9",
    "@angular/core": "8.2.9",
    "@angular/forms": "8.2.9",
    "@angular/http": "6.0.7",
    "@angular/material": "8.2.2",
    "@angular/platform-browser": "8.2.9",
    "@angular/platform-browser-dynamic": "8.2.9",
    "@angular/router": "8.2.9",
    "@ngrx/core": "^1.2.0",
    "@ngrx/effects": "^8.3.0",
    "@ngrx/entity": "^8.3.0",
    "@ngrx/store": "^8.3.0",
    "@ngrx/store-devtools": "^8.3.0",
    "agm-direction": "^0.7.5",
    "angulartics2": "6.2.0",
    "bootstrap": "^4.1.1",
    "core-js": "^2.5.7",
    "jasmine-marbles": "^0.4.1",
    "jquery": "^3.3.1",
    "ldclient-js": "^2.8.0",
    "material-design-icons": "^3.0.1",
    "moment": "^2.22.2",
    "ng2-signalr": "^6.0.0",
    "roboto-fontface": "^0.9.0",
    "rxjs": "^6.5.3",
    "signalr": "^2.3.0",
    "typeface-roboto-mono": "0.0.75",
    "vanilla-text-mask": "^5.1.1",
    "zone.js": "^0.9.1"
  },
  "devDependencies": {
    "@angular/cli": "8.3.8",
    "@angular/compiler-cli": "8.2.9",
    "@angular/language-service": "8.2.9",
    "@angularclass/hmr": "^2.1.3",
    "@types/jasmine": "^2.8.8",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "^6.0.114",
    "codelyzer": "^4.4.2",
    "grunt": "^1.0.3",
    "grunt-bump": "^0.8.0",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^2.0.4",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.4.3",
    "karma-jasmine": "^1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "3.5.3"
  },

tsconfig.json is as follows:

  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  },

tsconfig.app.json is as follows:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "es2015",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

Per SO comment request for .ts and .html (loading-indicator):

import {
  Component,
  EventEmitter,
  Input,
  OnDestroy,
  OnInit,
  Output,
} from '@angular/core'
import {
  Observable,
} from 'rxjs'
import {
  takeWhile,
} from 'rxjs/internal/operators/takeWhile'

import {
  FadeInOut,
} from '../animations/fade-in-out.animation'
import {
  ConfirmationModalStates,
} from '../models/confirmation-modal.model'

@Component({
  selector: 'loading-indicator',
  templateUrl: './loading-indicator.component.html',
  styleUrls: ['./loading-indicator.component.sass'],
  animations: [
    FadeInOut()
  ]
})
export class LoadingIndicatorComponent implements OnDestroy, OnInit {

  // The icon used during the "Failure" state. Defaults to 'call' in the template
  // The Success icon is always a check-mark
  // The warning icon is always an exclamation-mark
  @Input() failureIcon
  // The headline text to show while loading 
  // Also used to change style in case of loading
  @Input() loadingText = ''
  @Input() stateStream$: Observable<ConfirmationModalStates>
  // The headline text to show when warning
  @Input() warningText: string
  @Output() failureClick = new EventEmitter<void>()
  @Output() successfulClick = new EventEmitter<void>()

  // Expose the states so the UI can refer to enum values
  public LoadingStates = ConfirmationModalStates
  public spinnerValue = 0
  public state: ConfirmationModalStates = ConfirmationModalStates.Loading

  private subscriptionsAreActive = true

  constructor() { }

  ngOnDestroy() {
    this.subscriptionsAreActive = false
  }

  ngOnInit() {
    this.initSubscriptions()
  }

  public genericAction() {
    // It's unclear why these output events are registered as not tested. They are
    /* istanbul ignore next */
    if (this.state === ConfirmationModalStates.Success) {
      this.successfulClick.emit()
    } else if (this.state === ConfirmationModalStates.Failure) {
      this.failureClick.emit()
    }
  }

  /**
   * Animates completing the loading circle
   */
  private completeCircleAsync() {
    // Start it a little ahead to give the user the feeling of progress
    this.spinnerValue = 10
    const myTimeout = setInterval(() => {
      this.spinnerValue += 15
      if (this.spinnerValue >= 100) {
        clearInterval(myTimeout)
      }
    }, 90)
  }

  private initSubscriptions() {
    this.stateStream$.pipe(
      takeWhile(() => this.subscriptionsAreActive)
    ).subscribe(newState => {
      this.state = newState
      // It's unclear why these output events are registered as not tested. They are
      /* istanbul ignore next */
      if (newState !== ConfirmationModalStates.Loading) {
        this.completeCircleAsync()
      }
    })
  }
}
<div class="text-center" [ngClass]="{
      'clickable': (state === LoadingStates.Success || state === LoadingStates.Failure)
}" (click)="genericAction()">
  <div class="spinner-wrapper">
    <mat-progress-spinner [ngClass]="{
      'spinner-fail': state == LoadingStates.Failure,
      'spinner-prompt': state == LoadingStates.Prompt,
      'spinner-success': state == LoadingStates.Success,
      'spinner-warn': state == LoadingStates.Warning
    }" [mode]="'determinate'" [value]="spinnerValue" [strokeWidth]=3 *ngIf="state !== LoadingStates.Loading" [@fadeInOut]>
    </mat-progress-spinner>
  </div>
  <div class="spinner-icon" [@fadeInOut]>
    <i class="material-icons text-warning" *ngIf="state == LoadingStates.Failure">{{failureIcon || 'call'}}</i>
    <i class="material-icons text-primary" *ngIf="state == LoadingStates.Prompt">more_horiz</i>
    <i class="material-icons text-success" *ngIf="state == LoadingStates.Success">check</i>
    <i class="material-icons text-warning" *ngIf="state == LoadingStates.Warning">{{failureIcon || 'priority_high'}}</i>
  </div>
</div>

<div [ngSwitch]="state">
  <div class="clickable" *ngSwitchCase="LoadingStates.Success" [@fadeInOut] (click)="genericAction()">
  </div>
  <div class="content" *ngSwitchCase="LoadingStates.Warning">
    <p class="headline text-uppercase text-warning">
      {{warningText || 'Warning'}}
    </p>
  </div>
  <div class="content clickable" *ngSwitchCase="LoadingStates.Failure" (click)="genericAction()" [@fadeInOut]>
    <p class="headline text-uppercase text-warning">
      {{warningText || 'Call'}}
    </p>
  </div>
  <div *ngSwitchCase="LoadingStates.Loading">
    <div [@fadeInOut] [class.login-loading]="!!loadingText">
      <div class="spinner-wrapper pt-5">
        <mat-spinner class="spinner-loading" [strokeWidth]=3></mat-spinner>
      </div>
    </div>
    <div class="content">
      <p class="headline text-uppercase">
        {{loadingText}}
      </p>
    </div>
  </div>
</div>

If you have additional insights as to how to resolve this, that'd be appreciated!

UPDATE 2022.01.14

  • The loading-indicator.component.html, but more important, the entire Angular 8 web app leverages this pre-bootstrap loading screen technique as described by Ben Nadal's blog.

  • My text editor is VS Code alongside Windows 10 Pro with my web browser being Chrome Version 97.0.4692.71. That said, I've seen this issue on EDGE and Brave browser as well.

tao
  • 82,996
  • 16
  • 114
  • 150
markreyes
  • 1,249
  • 1
  • 13
  • 27
  • Can you paste the code for `loading-indicator.component`? The html and the ts. – Mathew Berg Jan 13 '22 at 03:59
  • Done. Please see above. – markreyes Jan 13 '22 at 04:18
  • 1
    Is there any chance you could create a *runnable* [mcve] on codesanbox.io or similar? Ideally it shouldn't contain your entire project, just enough to repro the bug. This has to do with one particular directive or component (they're the ones creating contexts on div elements). You could try pinpointing it down to its source by gradually removing components from your modules (and commenting out their tags in templates). Start by eliminating modules, one by one. – tao Jan 17 '22 at 14:22
  • 1
    Note in current form your question is not answerable, as there's no way to inspect the bug, narrow down its source or test a potential fix. – tao Jan 17 '22 at 14:28
  • I am also not sure whether this might break the build but in the component markup the `@fadeInOut` animation is left as a one-way binding, without an expression. I would simply leave it as `
    ....
    ` (this applies to all places where it's used without an expression). This is the only thing that looks weird to me, given the information provided. Otherwise, I agree that we need some more info.
    – ardentia Jan 18 '22 at 19:55
  • I am wondering about your animation `FadeInOut`. In your `@Component` decorator, you are actually calling the expression as if it were a function. Not sure if that would cause your issue, but it certainly does not seem right with the parenthesis (`FadeInOut()`) – Michael Doye Jan 20 '22 at 14:09
  • What happens if you move (for the sake of testing) your code from ngOnInit to ngAfterViewInit? – frosty Jan 20 '22 at 17:50
  • And... Does "ng serve" (instead "npm run start") work fine or does it throw the same error? – Juan Vicente Berzosa Tejero Jan 21 '22 at 17:39
  • take a diff between your packagelock.json now and with working version of code in git history as you do npm install it does not guarantee what is specified in your lock file will be downloaded. perhaps it might have updated any dependency. i suspect 'angulartics2', 'agm-direction', ng2-signalr may have upgraded if you want to resolve old package lock file use `npm ci` – niteshbisht Jan 21 '22 at 22:18
  • Thank you for your responses, everyone. I will have to go back to the drawing board on this in light of all suggestions here. Should I come up with a path, I'll update this SO post. – markreyes Jan 25 '22 at 23:20
  • I'm having the same issue. Also on Angular 8. I found some forum posts that hinted that this issue (or one very similar) might have been fixed in Angular 9. – blaster Feb 25 '22 at 17:53

2 Answers2

3

For me similar issue got solved by

  1. removing Extension "Angular Language Service" from VsCode
  2. Delete node modules and reinstalling them.
Dummy God
  • 43
  • 1
  • 6
  • 2
    I wish I had followed up on this because I did the exact same sequence. But in my case, I disabled the extension rather than removing it but I too deleted node_modules after the fact. Thanks for verifying! – markreyes Sep 30 '22 at 22:02
1

This is one of those moments in which you really don't know what to do... the Angular 8 project at hand stopped compiling out of nothing. It was working just fine in the same day ha! The console in Chrome Dev Tools (also on Firefox or Edge browsers dev tools) didn't give any more hints and there's no spot on answer available anywhere. So, you know what really solved it for me?

npm ci

Install a project with a clean slate

Description This command is similar to npm install, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies.

The difference I noted is that it made a lot of changes to the yarn.lock file updating package versions everywhere.

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480