2

How does one go about debugging the DOM as it renders? I searched around and couldn't find any clear answer. It's probably likely I'm just not searching on the right keywords... who knows.

For example, say you have an ng-repeat directive applied on a table row.

Lets say we have this in the template, which the directive uses:

<table class="table table-striped table-condensed">
  <tr ng-repeat="myObject in myObjects">
    <td>{{myObject.name}}</td>
    <td>{{myObject.description}}</td>
  </tr>
</table>

Then, within our directive, we set up a property of the scope, either in the link or within some controller:

    link: function (scope, element, attrs) {
      scope.myObjects= [{ name: 'foo', description: 'desc for foo' },
      { name: 'bar', description: 'desc for bar' },
      { name: 'baz', description: 'desc for baz' }];
...

This renders great. However how does one go about somehow being able to view the html as it gets rendered? Is there some way I could actually set some kind of breakpoint to look at the current iteration of what the "myObject" is (as well as all its properties I could access... such as "name" and "description") at each iteration?

Currently I'm using Visual Studio Code with chrome debugging tools, though this only works for the javascript.

Hopefully I'm asking this question correctly! If anyone could help me out I would greatly appreciate it. :)

dvsoukup
  • 1,586
  • 15
  • 31

1 Answers1

0

You can set breakpoints on DOM modifications, as shown in this answer. It probably won't work, though.

Most frameworks don't modify the DOM in the progressive manner you describe. The usual approach is to create element nodes in background, and then add the full updated set to the DOM.

For example (minimal but illustrative):

const node = document.createElement('div')

node.appendChild(document.createElement('h1'))
node.appendChild(document.createElement('p'))
node.appendChild(document.createElement('p'))

document.body.appendChild(node) // not actually added until this runs

So there's really no way to see the nodes "as they are added". The modifications tend to happen "at once", and rendering frameworks go out of their way to ensure the least amount of separate DOM modifications.

Modern frameworks, such as React, don't do even this. Instead, they have their own data structures to represent elements, and only modify the DOM in a synchronization stage (between the visible page and the abstract page they're managing) to actually render them, performing the minimum possible amount of operations (which may involve transforming elements instead of removing and adding).

Community
  • 1
  • 1
salezica
  • 74,081
  • 25
  • 105
  • 166
  • so when you're writing out the HTML and sprinkling it with data binding expressions... do you just hope for the best that you got it right? Seems like you'd have to write your data binding expressions and constantly reload the page. I mean, if I tried to bind to {{myObject.somethingElse}}, obviously it wouldn't work, but how can I view that I have an undefined property, or at least see the error message somewhere? – dvsoukup May 04 '17 at 19:41
  • A simple way to debug is to render a `
    ` element with the `JSON.stringify()` of the object you're trying to guess at. Other than that, you should move as much logic as possible into your controllers and factories, and make views as simple as you can
    – salezica May 04 '17 at 21:05