Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression.
For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
### I’m a library author. Should I run this migration?
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
### Full list of method migrations
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i <nodes.length;i++){appendChild(parentElement,nodes[i]);}`|
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i <viewRootNodes.length;i++){insertBefore(parentElement,viewRootNodes[i],nextSibling);}`|
|`detachView(viewRootNodes)`|`for (let i = 0; i <viewRootNodes.length;i++){constnode =viewRootNodes[i];constparentElement =parentNode(node);removeChild(parentElement,node);}`|
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i <viewAllNodes.length;i++){destroyNode(viewAllNodes[i]);}`|