AngularJS - "Error: The template must have exactly one root element" when using Angular-UI Typeahead

I am using AngularUI Typeahead on the index page of my application. I am not doing anything unusual - in fact, I'm just trying to get the example that they got on the UI workstation, and I get this error:

Error: Template must have exactly one root element 

I have no idea what this means, but this only happens when I have the following code:

 <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> 

If appropriate, my controller for my main page (which is called via $routeProvider for the / index directory):

 function indexCtrl($scope, $location, $resource) { $scope.selected = undefined; $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; } 

Note that the rest of the controller on the page is working perfectly, and just $scope.selected/$scope.states is causing problems. I canโ€™t understand what the error means, so troubleshooting is quite difficult!

Any ideas?

EDIT Here is my HTML template:

  <html ng-app="myApp" class="ng-scope"> <head> // Head stuff, probably irrelevant </head> <body> <div class="container"> <div ng-view="" class="row-fluid"> <form class="row-fluid"> <div class="container-fluid"> <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> </div> </form> </div> </div> // A bunch of Angular scripts are here </body> </html> 

It is definitely associated with a typeahead script, I can remove typeahead="state for state in states | filter:$viewValue" , and the script works (although, obviously, the typeahead function typeahead not ...)

+6
source share
5 answers

Make sure you add the correct ui-bootstrap-tpls-[version].min.js (tpls versions contain templates as well as code). You will need a script tag somewhere referencing the local or cdn version.

Most likely, this error is caused by the fact that angular cannot find a template for displaying typeahead parameters, trying to extract one of them via http and get 404 instead (with a new root html element, error).

+22
source

I had the same problem, but with the ui-select directive, but the general problem would be the same.

I could finally solve my problem, and I could determine that in my case the problem was that I added an HTTP interceptor to automatically add all HTTP requests to the server.

But as the token was added before the internal process could check the template cache, it ended that the requested file (bootstrap.select.tpl.html) was modified by my interceptor (bootstrap.select.tpl.html? Token = xxxxxx), and it was no longer known in the hach โ€‹โ€‹cache, and the server wanted to download it from the server. But on the server, I was not able to resolve the url request, and I am responding to the default webpage.

I modified my interceptor to check if the requested URL was requested in the cache and add only a token if the page was not found in the cache. After that, everything went fine.

Hope someone can benefit from such a solution

 /** * Intercept all http-Traffic to add the token */ app.config( function ($httpProvider) { $httpProvider.interceptors.push(function ($q, $rootScope, $localStore, $templateCache) { return { request: function (config) { // check if the cache has the file already loaded, in this case do not append any token if (!$templateCache.get(config.url)) { if (!config.params) config.params = {}; var token = $rootScope.token; if (token !== null && token !== undefined && token !== 'undefined') { $localStore.set('token', token); // only if it a valid token, add it config.params.token = token; } } return config || $q.when(config); } }; } ); } ); 
+2
source

your indexCtrl not listed in your html (ng-controller). You should not initialize the selected variable with undefined use $scope.selected = ''; or just delete it. This code works:

 <div class="container"> <div ng-controller="mainCtrl" class="row-fluid"> <form class="row-fluid"> <div class="container-fluid"> <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> </div> </form> </div> </div> angular.module('myApp', ['ui.bootstrap']) .controller("mainCtrl", function ($scope) { $scope.selected = ''; $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; }); 

JSFiddle: http://jsfiddle.net/alfrescian/EDZgT/

+1
source

you also need to wrap the template file with one element (including comments). more details here

0
source

meet the sam problem, and found my mistake. I have removeAll templateCache which will cause the whole template to not work

0
source

Source: https://habr.com/ru/post/949432/


All Articles