Debugging Like a Boss in Angular 9
Anthony Humes
Debugging
This is going to rock!
What happens next?
What can we learn?
to be able to debug any application, you have to understand the tools you can use
ng.probe
New API in Angular 9
Comes directly from Ivy internal methods
Where can I access the new methods?
// Global variable in the console
ng
{
getComponent: ƒ getComponent(element),
getContext: ƒ getContext(element),
getListeners: ƒ getListeners(element),
getOwningComponent: ƒ getOwningComponent(elementOrDir),
getHostElement: ƒ getHostElement(componentOrDirective),
getInjector: ƒ getInjector(elementOrDir),
getRootComponents: ƒ getRootComponents(elementOrDir),
getDirectives: ƒ getDirectives(element),
applyChanges: ƒ applyChanges(component)
}
Before we start...what is $0?
$0
<p class="some-element"></p>
<div class="some-div">
<p class="some-element">
Hey there text!
</p>
</div>
most recent selection from the Elements Inspector or from using Inspect Element
Get Angular Elements
ng.getComponent
ng.getDirectives
ng.getListeners
ng.getComponent
ng.getDirectives
ng.getListeners
retrieves the component from an HTML element
retrieves an array of directives from an HTML element
returns an array of both html (ex. click) and host listeners for an HTML element
ng.getComponent
<app-parent class="some-div">
<app-child class="some-element">
Hey there text!
</app-child>
</app-parent>
ng.getComponent($0)
ChildComponent {...}
ng.getDirectives
<app-element class="some-div">
<p appExample appOther class="some-element">
Hey there text!
</p>
</app-parent>
ng.getDirectives($0)
[ExampleDirective {...}, OtherDirective {...}]
ng.getListeners
export class ExampleComponent {
@HostListener('mouseover', ['$event'])
onHover($event: MouseEvent) {
// some action on hover
}
}
ng.getListeners($0)
[{
element: app-example,
name: "mouseover",
callback: f wrapListenerIn_markDirtyAndPreventDefault(e),
useCapture: false,
type: "dom"
}]
<app-element class="some-div">
<p (click)="itemClicked($event)" class="some-element">
Hey there text!
</p>
</app-parent>
ng.getListeners
<app-element class="some-div">
<p (click)="itemClicked($event)" class="some-element">
Hey there text!
</p>
</app-parent>
ng.getListeners($0)
[{
element: p.some-element,
name: "click",
callback: f wrapListenerIn_markDirtyAndPreventDefault(e),
useCapture: false,
type: "dom"
}]
Why ng.getComponent?
- Debug specific components in isolation
- Debug *ngFor by looking at specific items
Why ng.getDirectives?
- Discover all directives attached to a
specific element - Make changes to specific instances
of directives
Why ng.getListeners?
- Discover all listeners attached to
an element - Run listeners without triggering
the corresponding event
ng.applyChanges
let component = ng.getComponent($0)
component.value = 10;
ng.applyChanges($0)
<app-element class="some-div">
<p class="some-element">
5
</p>
</app-parent>
<app-element class="some-div">
<p class="some-element">
10
</p>
</app-parent>
triggers change detection for the component or directive
Why ng.applyChanges?
- Debugging Change Detection Issues
- Testing the effect of changes made to
components/directives
ng.getOwningComponent
ng.getContext
ng.getOwningComponent
<app-element class="some-div">
<p class="some-element">
Hey there text!
</p>
</app-parent>
ng.getOwningComponent($0)
ExampleComponent {...}
ng.getContext
<ul>
<li><app-item></app-item></li>
<li><app-item></app-item></li>
<li><app-item></app-item></li>
<li><app-item></app-item></li>
<li><app-item></app-item></li>
</ul>
ng.getContext($0)
NgForOfContext {
first: false
last: false
even: true
odd: false
$implicit: {name: "Item 3", value: {…}}
ngForOf: (5) [{…}, {…}, {…}, {…}, {…}]
index: 2
count: 5
}
Why ng.getOwningComponent?
- Use in concert with applyChanges to
run change detection for wrapping
component - Get the component for any element
in the DOM
Why ng.getContext?
- Debug instances of *ngFor and *ngIf
structural directives - Get the context for elements inside
of *ngFor
ng.getOwningComponent
returns the parent component for the HTML element
ng.getContext
returns the context of an *ngIf or *ngFor for the HTML element
Other Methods
ng.getRootComponents
ng.getInjector
ng.getRootComponents
Retrieves all root components associated with a DOM element, directive or component instance.
Root components are those which have been bootstrapped by Angular.
ng.getInjector
Retrieves an `Injector` associated with an element, component or directive instance.
Note from the Angular Team
The current API is a work in process. These methods are the starting point to a way more powerful set of debug tools than ng.probe. More methods and better functionality will be coming in the future.
Demo
Next Steps
- Experiment with the new methods
- Spend some time pair programming with another developer
- Help someone in the community with a problem they can't solve
- Always keep learning!
Debugging Like a Boss in Angular 9 - Full
By Anthony Humes
Debugging Like a Boss in Angular 9 - Full
- 883