# Trouble migrating from Au1 to Au2 where certain technical APIs are being utilized

**URL:** <https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320>\
**Category:** Framework Knowledge\
**Created:** [January 5, 2025, 9:32pm UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320 "2025-01-05T21:32:41Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 5, 2025, 9:32pm UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/1 "2025-01-05T21:32:41Z")

</div>

Hello,

I am continuing the journey of migrating from Au1 to Au2, and have reached the point of integrating Devextreme (from DevExpress), which I will abbreviate as **Dx**.

**BACKGROUND**

In our Au1 application, I have successfully integrated **Dx** , even to the extent of marrying Aurelia’s templating to **Dx** ’s templating through the `integrationOptions` property on those **Dx** components which support `dx-template`s.

It would appear that a number of API’s have moved, changed, or been eliminated. Consider the imports from my `DxAuTemplateService`:

```auto
import { inject, TemplatingEngine, View, ViewResources } from 'aurelia-framework';
import { createOverrideContext } from 'aurelia-binding';

```

Of course, I now import `inject` from ‘aurelia’.

I know from the documentation that `TemplatingEngine` is now under the **Enhance API** in Au2. And that’s fine. I just have to change the method call to reflect the new signature (I’ll work on that later). From our Au1 application, I have:

```auto
// Here, we build an Aurelia view from all of the moving parts
const view = this.templatingEngine.enhance({
    element: element,
    bindingContext: itemBindingContext,
    overrideContext: itemOverrideContext,
    resources: viewResources,
});

```

Finally, it would appear that `@noView` and `@processContent` have changed as well. I haven’t been able to migrate the following use case (i.e., the specific combination of the two decorators below):

```auto
@noView()
@processContent(false)
export class TsiDxButton() {
    ...
}

```

I learned the above approach from the two Vimeo training courses offered by Rob Eisenberg himself a number of years ago (see Question #3 below for a fuller discussion).

Also, know that I have successfully wrapped **DxButton** from **Dx** , but have not yet been able to bring Aurelia’s templates together with **Dx** ’s. That’s what the questions below address.

**QUESTIONS**

**1. What happened to `#createOverrideContext`?**

```auto
import { createOverrideContext } from 'aurelia-binding';

```

I use it in the following way (first branch of the `if` below):

```auto
...

if (model) {
    itemBindingContext = {
        data: model, // Push an Aurelia model into the data property
    };

    // Not strictly necessary, but assists Aurelia with scope hierarchy traversal
    itemOverrideContext = createOverrideContext(
        scope.bindingContext,
        scope.overrideContext
    );
} else {
    // Here, we just reuse the parent scope; not all dx-templates are associated with
    // data (a model)
    itemBindingContext = scope.bindingContext;
    itemOverrideContext = scope.overrideContext;
}

const view = this._createAureliaViewFromTemplate(
    newElement,
    itemBindingContext,
    itemOverrideContext,
    scope.owningView.resources
);

...

```

**2. What happened to `ViewResources`?**

I know that `View` is now `EnhancedView`. But what happened to `ViewResources`? I use them only in contract language to make sure I’m working with instances of these classes. So they aren’t strictly necessary for the template service to work. But I place many contracts around third-party API usages in order to detect intimate changes in those APIs:

```auto
...

require: {
    element, 'Element exists';
    itemBindingContext, 'Item binding context exists';
    itemOverrideContext, 'Item override context exists';
    viewResources instanceof ViewResources,
        'View resources are of type ViewResources (Aurelia)';
}

...

return view;

ensure: {
    result, 'Aurelia view exists';
    result instanceof View, 'View is of type View (Aurelia)';  
    // I know that View will become EnhancedView
}
    

```

**3. How do we migrate the following decorator chord?:**

```auto
@noView()
@processContent(false)

```

With Dx components, `@noView` allows the component to take over the view. I have determined that the new pattern for that in Au2 is the following:

```auto
@customElement({
    name: 'dx-button',
    template: null,
)

```

where `template: null` is the equivalent of `@noView`.

`@processContent` is a bit trickier. Consider the following two snippets from our Au1 application:

```auto
@noView
@processContent(false)
@inject(Element, DxAuIntegrationService, CustomEventDispatcher)
export class DxSelectBox extends DxTextualInputBase {
...
}

```

```auto
<dx-select-box items.bind="typeOptions" value-expr="id"...>
    <dx-template name="item">
        <div innerhtml.bind="data.type"></div>
    </dx-template>
    <dx-template name="field">
        <dx-text-box is-static.bind="true" value.bind="data.typeUnformatted">
        </dx-text-box>
    </dx-template>
</dx-select-box>

```

It would appear that Au2 strips out anything between the custom element’s tags. The way my template services works, I harvest the `DX-TEMPLATE` elements, ingest them into the template dictionary, and then pass that dictionary to the **Dx** component’s `integrationOptions`, as specified by the DevExpress team. After the ingest, I delete the `DX-TEMPLATE` elements as they are no longer needed.

`@processContent(false)` simultaneously allows me to have content but suppress it in the view (because it’s going to be processed by me and removed).

How do achieve this scenario in Au2? This was explicitly covered in Rob’s course, and I use it in our Au1 application with great success!

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [January 6, 2025, 3:22am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/2 "2025-01-06T03:22:41Z")

</div>

1. For `@noView`:

* * *

1. For `@processContent(false)`:  
Thanks for explaining the intention. It can be achieved in v2 via the data property on the instruction of the custom element instance

```ts
import { resolve, IInstruction } from 'aurelia';
import { HydrateElementInstruction } from '@aurelia/template-compiler';

@processContent((node, platform, instructionData) => {
  instructionData.template = node.querySelector('dx-template');
})
export class DxSelectBox {
  constructor() {
    const { data } = resolve(IInstruction) as HydrateElementInstruction;
    const template = data.template;
    // do your stuff here
  }  
}

```

As you noted you’ll delete the `<dx-template>` after the extraction during the compilation, I think the above should suffice.

* * *

1. For the post itself:

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [January 6, 2025, 3:40am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/3 "2025-01-06T03:40:13Z")

</div>

1. For the question 1:

2. For the question 2:

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 6, 2025, 3:46am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/4 "2025-01-06T03:46:37Z")

</div>

Thanks for your insight on this!

I do see a rub, though, with the following fragment:

```auto
instructionData.template = node.querySelector('dx-template');

```

Often times, there is more than one `dx-template` in the markup for a particular **Dx** component (especially true of that gargantuan **DxGrid** ).

But now, as I write this, I just remembered that templates in Au2 can be multi-rooted. We no longer have to bracket the template with `<template>`. So, then, perhaps `#getElementsByTagName` will give me access to the full set.

I’ll work on this in a bit (you’ve given me a lot of insight to digest).

I can see now that I need to work towards full understanding of the migration to the new API’s, at which point I will be sure to post here for everyone’s consideration and contemplation.

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [January 6, 2025, 3:50am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/5 "2025-01-06T03:50:55Z")

</div>

If we had:

```html
<dx-select-box>
  <dx-template name="item">...</dx-template>
  <dx-template name="field">...</dx-template>
  <dx-template name="justInCase">...</dx-template>
</dx-select-box>
<dx-select-box>
  <dx-template name="item_in_another_usage">...</dx-template>

```

You can easily get any information you like, like this

```ts
@processContent((node, _, data) => {
  data.itemTemplate = node.querySelector('dx-template[name="item"]');
  data.fieldTemplate = node.querySelector('dx-template[name="field"]');
  data.justInCseTemplate = node.querySelector('dx-template[name="justInCase"]');
  data.item_in_another_usage = node.querySelector('dx-template[name="item_in_another_usage"]');
})

```

and so on.

Note that in the 2nd usage of `<dx-select>`, the first three `querySelector` calls all return null, while in the first `<dx-select>` usage, the last `querySelector` call returns null.

The example was to emphasize that there’s not been really any change in the APIs, except that we now have an official way to associate the element usage in the template with the instruction instance, which is injectable in element constructors.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 6, 2025, 4:03am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/6 "2025-01-06T04:03:18Z")

</div>

I just gave this a try (from your first example), I since I’m not using TypeScript, I had to translate. I think I’m missing something, though. I did this:

```auto
...

import { HydrateElementInstruction } from '@aurelia/template-compiler';
import { DxBase } from './dx-base';

import Button from 'devextreme/ui/button';

@inject(Element, CustomEventDispatcher, HydrateElementInstruction)
@customElement({
    name: 'dx-button',
    template: null,
    processContent: (node, platform, instructionData) => {
        instructionData.template = node.querySelector('dx-template');
    },
})
export class DxButton extends DxBase {
    ...
    constructor(element, eventDispatcher, instruction) {
        super(element, eventDispatcher);

        console.log(instruction); // <-- I do get an instruction, but I'm skeptical

        const { data } = instruction; // <-- This is where it fails
        const template = data.template;
    }
}

```

Should I be accessing the container directly to resolve `HydrateElementInstruction`?

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 6, 2025, 4:14am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/7 "2025-01-06T04:14:51Z")

</div>

I have to start winding down this evening. Tomorrow’s our first full day back from the holiday.

I see I have a number of replies to make:

- I’ll provide as a migration specimen the full template service that I wrote for processing `dx-template`s into **Dx** components as Aurelia enhancements (it’s not terribly complex).
- Initiate/facilitate a GH request around `#createOverrideContext`, or a least its equivalent cc @Sayan751 @fkleuver .
- Get back to you with the `makes` one-liners you requested.

Concerning `@noView`, it would indeed add semantic clarity. But, honestly, `template: null` doesn’t require a huge leap of assumption either. Perhaps, to protect developers, it should have to be `null` specifically. Maybe `undefined` and `false` should throw an exception?

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [January 6, 2025, 4:23am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/8 "2025-01-06T04:23:25Z")

</div>

> [@estaylorco](#):
>
> ```auto
> @inject(Element, CustomEventDispatcher, HydrateElementInstruction)
> 
> ```

It should be

```ts
@inject(Element, CustomEventDispatcher, IInstruction)

```

The interface is `IInstruction` and the instrance is actually a `HydrateElementInstruction`.

If you just inject `HydrateElementInstruction`, you’ll get an irrelevant instance, constructed anew.

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [January 6, 2025, 4:25am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/9 "2025-01-06T04:25:13Z")

</div>

> [@estaylorco](#):
>
> - Get back to you with the `makes` one-liners you requested.

It’s for the next time you report a scaffolding issue. For the css issue, it’s resolved [fix: fix webpack config on css by 3cp · Pull Request #116 · aurelia/new · GitHub](https://github.com/aurelia/new/pull/116/files)

> Concerning `@noView` , it would indeed add semantic clarity. But, honestly, `template: null` doesn’t require a huge leap of assumption either. Perhaps, to protect developers, it should have to be `null` specifically. Maybe `undefined` and `false` should throw an exception?

`undefined` is considered nullish, just like `null` so it’ll likely be fine. `false` is an interesting value, maybe we can throw if neither nullish or string to guard the APIs, in case of future expansion. For `@noView`, it may help ease the unnecessary manual work during migration, not a bad thing, maybe I’ll cc @Sayan751 since he also did it.

---

<div class="post-metadata">

**Author:** ![Sayan751](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sayan751/32/1861_2.png) [@Sayan751](https://discourse.aurelia.io/u/Sayan751)\
**Post date:** [January 6, 2025, 7:57pm UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/10 "2025-01-06T19:57:51Z")

</div>

Created this GH issue: [Implement @noView and @inlineView like au1 · Issue #2085 · aurelia/aurelia · GitHub](https://github.com/aurelia/aurelia/issues/2085)

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 6, 2025, 10:19pm UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/11 "2025-01-06T22:19:58Z")

</div>

Thank you for opening that issue.

This evening, I’m going to finish implementing—or at least try to—guidance that @bigopon gave me in dealing with the absence of `@processContent(false)`. Unless anyone objects, I might open an issue recommending `@processContent(false)`. I bring it up here because it goes hand-in-hand with `@noView` in those cases where a third-party component takes over the view, but there’s still a need to process markup into, or against, the component’s instance.

I say “might” above because it’s going to depend on the shape of the code necessary to deal with the absence of `@processContent(false)`.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 7, 2025, 1:03am UTC](https://discourse.aurelia.io/t/trouble-migrating-from-au1-to-au2-where-certain-technical-apis-are-being-utilized/6320/12 "2025-01-07T01:03:06Z")

</div>

I have created a GH request ([Port #createOverrideContext (from Au1 'aurelia-binding') to Au2 · Issue #2086 · aurelia/aurelia · GitHub](https://github.com/aurelia/aurelia/issues/2086#issue-2771694174)) for `createOverrideContext`.
