angular: [RC6][REGRESSION][ngUpgrade] Error: Only selectors matching element names are supported

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting

Current behavior With RC5 it’s working fine. With RC6: Error: Only selectors matching element names are supported, got: [alertManagerRow].

Reproduction of the problem http://plnkr.co/edit/PvVWdDG5RfN7ZzVn0gUu?p=preview

Please provide a way to implement it, as you can see in the plunkr, it cannot be used as a non-attribute definition.

Please tell us about your environment:

  • Angular version: 2.0.0-rc.6
  • Browser: [all ]
  • Language: [TypeScript 2.0.2 | ES5 | SystemJS ]

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 9
  • Comments: 30 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Regardless if it is antipattern or not it should not be upgrade making the check. I will have a look and should have a PR shortly.

@vicb let us know if you need any more details

the fix is in 2.0.1

Looking at the code, this issue seems to have been introduced by this commit https://github.com/angular/angular/commit/4a740f23a447d7201fe655e2f016b70066752ec1

                ._bootstrapModuleWithZone(
                     DynamicNgUpgradeModule, undefined, ngZone,
                     (componentFactories: ComponentFactory<any>[]) => {
                       componentFactories.forEach((componentFactory) => {
                         componentFactoryRefMap[getComponentInfo(componentFactory.componentType)
                                                    .selector] = componentFactory;
                       });
                     })

_bootstrapModuleWithZone is now called with a callback which is, according to the comment left in the code, an ugly internal api hack 😃

// ugly internal api hack: generate host component factories for all declared components and
 // pass the factories into the callback - this is used by UpdateAdapter to get hold of all
 // factories.

We have updated to angular 2.0.0 final and the problem described by dions00 in his plunker is still there http://plnkr.co/edit/44uWEp?p=preview . Are we doing something wrong ? Is there any workaround ?

Current behaviour With RC6 using ngUpgrade we cannot create directives like this:

@Component({
  selector: '[alertManagerRow]',
  template: `
  <td>foo</td>
  <td>bar</td>
  `
})

Use case:

<table>
        <thead>
          <tr>
            <th>1st column</th>
            <th>2nd column</th>
          </tr>
        </thead>
        <tbody>
          <tr alertManagerRow [number]="777"></tr>
          <tr alertManagerRow [number]="333"></tr>
        </tbody>
      </table>

Error: zone.js:461 Unhandled Promise rejection: Only selectors matching element names are supported, got: [alertManagerRow] ; Zone: <root> ; Task: Promise.then ; Value: Error: Only selectors matching element names are supported, got: [alertManagerRow]

With RC5 was working perfectly.

Expected behaviour Rendering of directive without any error. As it works without using ngUpgrade. It was working in RC5.

Steps to reproduce Just see console error in this plunkr: http://plnkr.co/edit/ImXKSq0EOM80kVtaJVpQ?p=preview

@mhevery Thank you for the fix. I tried it this morning and it works perfectly. When can we expect an angular release containing your fix ?

Like dions00 has pointed out, if only the COMPONENT_SELECTOR regular expression was containing the support of the square brackets in selector, it would work like a charm.

var COMPONENT_SELECTOR = /^[\w|-]*$/; //The square brackets are not included

something like this would work var COMPONENT_SELECTOR = /^\[*[\w|-]*\]*$/;

See my comment: https://github.com/angular/angular/issues/7026#issuecomment-223749101

Here we’re not downgrading any @Component just declaring and using it in a Angular 2 context. It works on all release candidate versions except for RC6.

@IgorMinar thanks for looking into this issue.

UI-Router is blocked by the latter (import a module with an ng2 component with an attribute selector).

What is not clear to me and I’d really like to understand why is there a need for Angular 2 components to use attribute selectors instead of element selectors. Can someone please explain the use-cases where attribute-selectors are absolutely needed?

Attribute selectors might be necessary when the tag types are important. Something like <tr my-fancy-row> comes to mind. The <title> example by @amcdnl <title> also seems like a reasonable expectation.

The fact that we currently enforce this in angular/upgrade but not in angular/compiler is an oversight on our part.

Will that restriction be added and enforced in some future version of angular?

In UI-Router, we don’t absolutely need <div ui-view='header'>. An element selector <ui-view name="header"> is fine. The assumption was that attribute selectors were supported for Components, so we added one. If the One True Way is to use only element selectors and that will be enforced at some point, I can live with that answer.

@IgorMinar -

  1. Are you are suggesting that attribute selectors are an anti-pattern?
  2. In Angular1/2, I use attribute selector for things like tooltips for instance. I want to ‘enhance’ the ordinary ‘title’ tag to have a fancy tooltip. By doing it like this it keeps the standard HTML syntax with a enhancement via angular. Additionally, there are situations where you might want to have tooltips on elements that have strict parent-child hierarchy such as SVGs. You can not wrap SVGs, so what I do is use a attribute title tag to the element, angular will then append the actual tooltip content to the body of the page and use positioning to place the tooltip appropriately.

this is definitely a blocker for people using the UpdateAdapter. we are facing this with ng-bootstrap currently while trying to upgrade JHipster to ng2

Trying to use ng-bootstrap also results in this issue. Even though I’m not downgrading any of the ng-bootstrap components, I get this error when trying to bootstrap using ngUpgrade:

Error: Only selectors matching element names are supported, got: [ngbDatepickerMonthView]

To be clear, I’m not using the date picker at all. Indeed, I’m not yet using any ng-boostrap component - merely to include the service.

We have the same issue on our project but with SVG attribute (rc.6). The application is working well with rc.5

@Component({
    selector: "[label]",
    template: `<svg:text x="0" y="15" fill="red">I love SVG!</svg:text>`
})
class LabelComponent {
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <svg height="30" width="200">
        <svg:g label></svg:g>
      </svg>
    </div>
  `,
})
export class App {
  constructor() {
    this.name = 'Angular2'
  }
}

Everything works fine without the UpgradeAdapter, plunk: http://plnkr.co/edit/w7Tw38KAZOlNCluliKR1?p=preview

“Only selectors matching element names are supported” error with UpgradeAdapter, just see console error in this plunk: http://plnkr.co/edit/44uWEp?p=preview

The issue is with these lines. In my example, the selector contains square brackets: [label] https://github.com/angular/angular/blob/master/modules/@angular/upgrade/src/metadata.ts

var COMPONENT_SELECTOR = /^[\w|-]*$/;                //The brackets are not included
if (!selector.match(COMPONENT_SELECTOR)) {
    throw new Error('Only selectors matching element names are supported, got: ' + selector);
}

Thank you

I definitively agree with @IgorMinar that a tooltip shouldn’t be a component but rather a directive. This is what we do in ng-bootstrap as well: https://github.com/ng-bootstrap/ng-bootstrap/blob/40bde5e09d292cc714e41b1783c5bcb8e1cbd067/src/tooltip/tooltip.ts#L39

As Igor mentioned I’m going to have a look at other table-related use-cases tomorrow (tables seem to be the most restrictive when it comes to which elements you can stick between table / tbody / tr) to see what happens with other projects in the wild.

I’ve got the second problem you’ve listed, via ng-bootstrap. I don’t have an opinion as to whether attribute selectors are right or wrong. I’ve just started with angular 2, and it’s not a great experience to have a problem with a well established library like ng-bootstrap.

If we determine that attribute selector for components should be banned then we are going to change ng-bootstrap impl within a day or 2.

This is a blocker for the UI-Router hybrid app adapter past rc.5

My understanding is that you can only ngUpgrade element selector based components.

I recall seeing this issue where it’s explained that attribute selectors will give ownership of the host element to both frameworks: https://github.com/angular/angular/issues/7026

@dions00 If I comment the line:

throw new Error('Only selectors matching element names are supported, got: ' + selector);

It’s working again, great! But hope to have an official fix soon. Thanks!

We have the same issue on our project. We are looking forward to have an answer on this one. Thank you

Please describe more clearly:

  • current behavior,
  • expected behavior,
  • steps to reproduce