Word counter in angularjs
It seems like you need to call 'trim' before calling split, like this:
$scope.getWordCounter = function() { return notesNode.text.trim().split(' ').length;}
If you want to support multiple spaces between words, use a regular expression instead:
$scope.getWordCounter = function() { return notesNode.text.trim().split(/\s+/).length;}
Filter implementation
You can also implement wordCounter
as a filter, to make it reusable among different views:
myApp.filter('wordCounter', function () { return function (value) { if (value && (typeof value === 'string')) { return value.trim().split(/\s+/).length; } else { return 0; } };});
Then, in the view, use it like this:
<span class="wordCount">{{notesNode.text|wordCounter}</span>
This is a more advanced answer for your problem, since it can be reusable as a directive:
var App = angular.module('app', []);App.controller('Main', ['$scope', function($scope){ var notesNode = { text: '', counter: 0 }; this.notesNode = notesNode;}]);App.directive('counter', [function(){ return { restrict: 'A', scope: { counter: '=' }, require: '?ngModel', link: function(scope, el, attr, model) { if (!model) { return; } model.$viewChangeListeners.push(function(){ var count = model.$viewValue.split(/\b/g).filter(function(i){ return !/^\s+$/.test(i); }).length; scope.counter = count; }); } };}]);
And the HTML
<body ng-app="app"><div ng-controller="Main as main"></div> <input type="text" ng-model="main.notesNode.text" class="county" counter="main.notesNode.counter"> <span ng-bind="main.notesNode.counter"></span></body>
See it in here http://plnkr.co/edit/9blLIiaMg0V3nbOG7SKo?p=preview
It creates a two way data binding to where the count should go, and update it automatically for you. No need for extra shovelling inside your scope and controllers code, plus you can reuse it in any other input.