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:
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:
- https://github.com/angular/angular/issues/24556
- Angular elements error . "Failed to construct 'HTMLElement ...'
- https://github.com/rangle/augury/issues/1464
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.