I'm getting the following error while implementing the AngularJS chosen directive.
Error:
TypeError: a.map is not a function
at nh.q.writeValue (angularjslatest.js:307)
at Object.e.$render (angularjslatest.js:328)
at angularjslatest.js:310
at angularjslatest.js:146
at m.$digest (angularjslatest.js:147)
at m.$apply (angularjslatest.js:150)
at l (angularjslatest.js:102)
at XMLHttpRequest.s.onload (angularjslatest.js:108)
I'm explaining my code below:
<select chosen
multiple
class="form-control oditek-form"
name="category"
id="category"
ng-model="category"
ng-options="s.value as s.name for s in listOfCategory">
</select>
My controller code is given below.
$scope.listOfCategory = [{
name: 'Select Category',
value: ''
}];
$scope.category = $scope.listOfCategory[0];
var fileURL = '';
var url1 = '../service/admin/vechile/service/service.php?action=getAllCategoryData';
var method = 'GET';
var data1 = '';
DataService.connectToServerSideScript(method, url1, data1).then(function(response) {
if (response.length > 0) {
angular.forEach(response, function(obj) {
var cdata = {
'name': obj.category_name,
'value': obj.id
};
$scope.listOfCategory.push(cdata);
})
}
}, function(error) {
});
Here I'm getting all the data but those error is coming in browser console. Here I need to clear those error.
You need to setup your selected model as an array:
$scope.category = angular.isDefined($scope.listOfCategory[0]) ?
[$scope.listOfCategory[0]] : [];
Please note that this also fixes the following error message:
Error: TypeError: a.forEach is not a function
I was facing a same kind of 'chosen multiple select' related problem, which was getting 3 times same error. Error log is like below. The solution may help others.
TypeError: a.map is not a function
at mh.q.writeValue (angular.js:30513)
at e.$render (angular.js:33327)
at Object.c.$render (angular-chosen.min.js:7)
at angular.js:29306
at m.$digest (angular.js:18253)
at b.$apply (angular.js:18531)
at HTMLButtonElement. (angular.js:27346)
at HTMLButtonElement.dispatch (jquery.min.js:3)
at HTMLButtonElement.q.handle (jquery.min.js:3)
To bypass the issue, I have maintained 2 variables, one for a model variable and other for a saving variable. e.g.
In controller,
$scope.x = {
draftVar: []
};
$scope.save = function(){
$scope.x.savingVar = $scope.x.draftVar.join(',');
save();
}
<select ng-model="x.draftVar" chosen multiple chosen-updater ng-options="xx.id as xx.name for xx in XXs">
<option value=""></option>
</select>
Related
Using Edistrap, once "tag" type is selected it throws error saying "uncaught type error, tagsInput.tagsinput is not a function". Traced code:
var tagsInput = html.find("input");
tagsInput.tagsinput({
tagClass : function(item) {
return 'label label-info';
}
});
html.removeClass("input-group-sm");
html.find(".bootstrap-tagsinput").addClass("form-control");
html.find(".validate").click(function() {
var allTags = tagsInput.tagsinput('items');
_this.submitEditable(span, allTags.join(_this.options.multipleSeparator), allTags);
});
I ain't no js programmer so I am asking if this is something I can fix easily.
Solution by Amy:
Include bootstrap-tagsinput.css & bootstrap-tagsinput.js
from https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/tree/master/src
Note that .css file needs to be edited in terms of colors to work with Editstrap.
I am not very good with angular, but i know some basics. Now, I have access points and want to assign them to a building. I can select this building with a <select>. I have written a simple controller, but it wont work. What am I making wrong, i cant find a solution.
Edit 1:
I can see the option fields (they are 3). But after I select one of these, my browser console throws the exception
Edit 2: Plunkr -> https://plnkr.co/edit/EIPs8yVlTSaYQ0EuZLTb (i hope, this url works) .. When you click on "Neuer Access-Point" the error will occur, after you select something on "Gebäude"
Select field
<select ng-model="$ctrl.input.building">
<option ng-repeat="building in $ctrl.buildings" ng-value="building.id" ng-bind="building.name"></option>
</select>
Controller
(function () {
function createController(Building) {
var ctrl = this;
ctrl.buildings = null;
ctrl.input = {
host: '',
desc: '',
web: '',
building: ''
};
ctrl.$onInit = function () {
Building.getAll().then(function (res) {
if (res.status >= 200 && res.status < 300) {
ctrl.buildings = res.data;
}
});
};
}
angular.module('app').controller('CreateController', createController)
})();
Error
angular.js:14791 Error: [$rootScope:inprog] http://errors.angularjs.org/1.6.8/$rootScope/inprog?p0=%24apply
at angular.js:88
at p (angular.js:18897)
at m.$digest (angular.js:18319)
at m.$apply (angular.js:18640)
at Object.$$debounceViewValueCommit (angular.js:29394)
at Object.$setViewValue (angular.js:29372)
at angular.js:33596
at m.$eval (angular.js:18533)
at m.$apply (angular.js:18632)
at HTMLSelectElement.<anonymous> (angular.js:33595)
Here is the issue with your code.
<div id="wrapper" ng-app="accessPoints" ng-controller="RootController **as $root**">
Change it to simply
ng-controller="RootController as anythingButNot$root"
or even just ng-controller="RootController"
Declaring any controller as $root is creating mess for you. $root is the root level controller of your application. Inside your html if you declare any controller as $root, it tries to overwrite $root, creating trouble with digest cycle, hence you are getting the error.
Link to updated plunk => https://plnkr.co/edit/UcJHVmekMqWMXJBnv2Cu?p=preview
I'm using a select form with data retrieved from a JSON url. When I select something, I want the value to be put into $scope.afspraak.groep. For some reason, the value returns to the original value which is empty.
Here is my code:
<select id="selectgroep" name="selectgroep" class="form-control" size='5' ng-model="afspraak.groep" ng-options="t.id as t.id for t in objecten" ng-click="test()">
</select>
$scope.afspraak = {
groep: '',
};
$scope.passData = function(data) {
$scope.afspraak.groep = data;
}
$scope.test = function() {
console.log($scope.afspraak);
}
I have used various methods such as changing ng-click to passData(afspraak.groep), but it still doesn't work. The weird thing is that in another partial, I have the exact similar code and that does work shown here:
<select id="selectvak" name="selectvak" class="form-control" size='5' ng-model="user.vakid" ng-options="t.id as t.id for t in vak" ng-click="getKlas(user.vakid); test()">
</select>
$scope.user = {
vakid: '',
};
$scope.test = function() {
console.log($scope.user);
}
$scope.getKlas = function (ID){
afsprakenService.getKlassen(ID)
.success(function (klas){
$scope.klas = klas;
$scope.alerts.push({ type: 'success', msg: 'Retrieved'});
})
.error(function (error) {
$scope.alerts.push({ type: 'danger', msg: 'Error retrieving! ' + error.message});
});
};
What am I doing wrong here? The only difference that I see is the method in the second select form which is getKlas where I pass the ng-model to use in another function.
Edit: this is now solved! It turns out that a label class is what was causing the deletion. I removed it by accident and it works now!
To set a models value from a select it is sufficient to have a ng-model on it. In case you want to do some extra action when selecting an option you should use ng-change and not ng-click.
A good way to debug your models, to check in real time if it was updated and view its values do something like this
<pre>{{ myModel | json }}</pre>
Here is a working fiddle example: http://jsfiddle.net/jub58sem/2/
In a template, I have:
<div ng-controller="projectListController as projects" class="pull-right" id="projectListDropDown">
<select ui-select2 id="projectListDD" placeholder="All" class="width240" ng-model="projects.projectSelection">
<option value=""></option>
<option ng-repeat="item in projects.projectList" value="{{item.WebsiteName}}">{{item.WebsiteName}}</option>
</select>
</div>
I want to populate the dropdown list from projectList below:
app.controller('projectListController', ['$rootScope', '$scope', '$log', 'abstractDataFactory', 'customUIFunctions', 'globalContainer',
function ($rootScope, $scope, $log, abstractDataFactory, customUIFunctions, globalContainer) {
dashboardGlobals = this.dashboardGlobals = globalContainer.dashboardGlobals;
var dataFactory = new abstractDataFactory("/odata/ProjectList");
var projectController = new abstractDataFactory("/Projects/ChangeCurrentProject") // load up projectDashboardDTO
this.selectProjectPlaceholder = "Loading Projects . . .";
this.filterItems = [
{ id: 1, text: 'Item1' },
{ id: 2, text: 'Item2' },
{ id: 3, text: 'Item3' },
{ id: 4, text: 'Item4' }
];
this.projectList = [];
// TODO; keep a global list of projects
// Get a list of current projects
dataFactory.getList("") // no parameters
.success(function (result) {
this.projectList = result.value; //<- array of objects is returned
dashboardGlobals.projectList = result.value;
this.selectProjectPlaceholder = "Select a project . . . "
$("#projectListSelection").select2({ width: '240' });
})
.error(function (error) {
customUIFunctions.showError("Data Error - Unable to Load Project List"); // use default error message
console.log("data error");
});
I have confirmed that there is data in result.value but the list remains blank.
However, when I use projects.filterItems in the ng-repeat, (along with id and text field names) the list is populated.
I also want the changed value to be globally accessible in Angular, so I injected my own globalContainer service into this controller, and whenever the page is refreshed, I want to ensure the selected value remains consistent, rather than resetting.
-- UPDATE --
The problem seems to be in the .success area, this.projectList is undefined. If I do var projectList = this.projectList = [] no error, but this doesn't seem right.
So the issue is with trying to define the variables after the fact, and using Controller as....
How can I get this working?
After reading something about half way down the page, here, and a bit more further understanding about the difference between $scope and this, in how they work in .success, I declared vm as a top-level this:
var vm = this;
vm.dashboardGlobals = globalContainer.dashboardGlobals;
var dataFactory = new abstractDataFactory("/odata/ProjectList");
var projectController = new abstractDataFactory("/Projects/ChangeCurrentProject") // load up projectDashboardDTO
vm.projectList = [];
.
.
.
dataFactory.getList("") // no parameters
.success(function (result) {
vm.projectList = result.value;
vm.dashboardGlobals.projectList = result.value;
vm.selectProjectPlaceholder = "Select a project . . . "
I am new to knockout.js and am having a problem with binding within a foreach section. I am receiving the error:
Uncaught Error: Unable to parse bindings.
Message: ReferenceError: hideSearchElements is not defined;
Bindings value: click: hideSearchElements
Here is an exert of the html:
<div id="searchResults" data-bind="visible: searchIsVisible">
<label id = "lblSearchResults">select a template:</label>
<div data-bind="foreach: titles">
<div data-bind="text: Title"></div>
<div data-bind="click: hideSearchElements">hide</div>
</div>
And an exert from the viewModel:
var viewModel = function () {
this.searchIsVisible = ko.observable(true);
this.showSearchElements = function () {
this.searchIsVisible(true);
};
this.hideSearchElements = function (
this.searchIsVisible(false); }
}
return new viewModel();
I have both showSearchElements and hideSearchElements working fine outside of the foreach block but when inside it, I get the error.
If I add $parent.hideSearchElements I can bind but then get an error saying:
Uncaught TypeError: Object # has no method 'searchIsVisible'
.
I have probably have two distinct issues but thought the detail may help :)
I'm keen to understand what's going on here? Can anyone help please?
A link to the relevant page in the documentation would also be very helpful - I'm reading through that now.
Thanks
You was right when use $parent.hideSearchElements because hideSearchElements function is in a parent context. You got exception because when knockout calls your function this has another context. You have to use closure to store this pointer. Update your view model as follow:
var viewModel = function () {
var self = this;
self.searchIsVisible = ko.observable(true);
self.showSearchElements = function () {
self.searchIsVisible(true);
};
self.hideSearchElements = function (
self.searchIsVisible(false); }
}