2

In angularJS 1.3.14

  var app = angular.module('myApp',[]);
  app.controller('myController',['$scope',function($scope){
 $scope.name = 'world';
  }]);
  //here i created directive of name helloWorld
  app.directive('helloWorld',function(){
    return {
 replace:true,
 restrict:'AE',
 template :'<h3>Hello world<h3/>'
   }
  });
<html ng-app='myApp'>
    <body ng-controller = "myController">
       <hello-world/>
    </body>
</html>
Error is :

Error: [$compile:tplrt] Template for directive 'helloWorld' must have exactly one root element.

How to solve this error?

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299

3 Answers3

1

Quick fix

Root cause(replace: true)

  1. <hello-world></hello-world>
  2. change directive template to close h3 tag properly template :'<h3>Hello world</h3>'

Explanation

There are two problem in your code.

  1. You should close your directive custom element like <hello-world><hello-world/>. If you do not close the tag, first occurrence will work fine but after that rest of the thing will not work. See here.
  2. Other thing is your template of directive has wrong template

Directive template

<h3>Hello world<h3/>

should be

<h3>Hello world</h3>

You have template in directive like <h3>Hello world<h3/> which has not closing the h3 tag properly.

So that gets rendered on page like below, which has two h3 element.

<h3>Hello world</h3>
<h3></h3>

So the render html has two elements which are individual. So while passing them to $compile service to compile the content of template, it is throwing [$compile:tplrt] which means your template should have single root element, so the angular will compile that element.

Partha Sarathi Ghosh
  • 10,936
  • 20
  • 59
  • 84
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
0

comment the replace: true.

var app = angular.module('myApp',[]);
        app.controller('myController',['$scope',function($scope){
            $scope.name = 'world';
        }]);

//**here i created directive of name helloWorld**
        app.directive('helloWorld',function(){
            return {
                restrict:'AE',
                //replace:true,
                template :'<h3>Hello world<h3/>'
            };
            });

or 

    //**here i created directive of name helloWorld**
            app.directive('helloWorld',function(){
                return {
                    restrict:'AE',
                    replace:true,
                    template :'<div><h3>Hello world<h3/></div>'
                };
                });
Yogesh
  • 773
  • 1
  • 8
  • 22
  • for the replace : true you need a single root element in the template. Your template does not meet that criteria.. other option is to surround yout template by
    restrict:'AE', replace:true, template :'

    Hello world

    '
    – Yogesh Dec 23 '15 at 09:07
  • It has `h3` tag as root elemnt. Except `h3` tag is not properly closed – Partha Sarathi Ghosh Dec 23 '15 at 09:19
0

You are getting the error because in your directive you are using replace:true and the template is enclosed in h3 tag winch is not closed properly (you should close h3 tag using </h3> not <h3/>).

You should enclose the template in a root tag properly like <h3>Hello world</h3>.

When a directive is declared with template (or templateUrl) and replace mode on, the template must have exactly one root element. That is, the text of the template property or the content referenced by the templateUrl must be contained within a single html element. For example, <p>blah <em>blah</em> blah</p> instead of simply blah <em>blah</em> blah. Otherwise, the replacement operation would result in a single element (the directive) being replaced with multiple elements or nodes, which is unsupported and not commonly needed in practice.

Reference : Angular Docs

Vivek
  • 11,938
  • 19
  • 92
  • 127