Problem with length!

Asked

Viewed 37 times

0

Hello! I am trying to implement, validation in some fields using knockoujs with the following code:

 <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            var registro;

            self.Nome = ko.observable(); 
            self.validacaoNome = ko.observable();           
            
            self.Nome.subscribe(function(value) {
    	         if (value.length < 5) {
        	         self.validacaoNome('O nome é inválido');
               } else {
	               self.validacaoNome(null);
               }
            });

            self.Numero = ko.observable();
            self.Email = ko.observable();
            self.Lista = ko.observableArray([]);
            self.Focus = ko.observable(true);

            self.Add = function() {
               if(self.Nome() && self.Numero() && self.Email()) {
                  var id = Math.floor(Math.random() * (10000 + 12));
                  for (var i = 0; i < self.Lista().length; i++) {
                     if (self.Lista()[i].id == registro) {
                        self.Lista().splice(i, 1);
                     }
                  }                
                  self.Lista.push(
                     { id: id, name: self.Nome(), contactNumber: self.Numero(), email: self.Email() }
                  );
               }     
               sort();                            
               clear();                       
            }              
            
            self.Alter = function(register) {
               registro = register.id;
               self.Nome(register.name);
               self.Numero(register.contactNumber);
               self.Email(register.email);
               self.Focus(true);                
            }           

            self.Remove = function() {
               self.Lista.remove(this);
               clear();
            }

            self.Clear = function() {
               clear();
               registro = null;               
            }

            self.afterProcess = function(elements) {
               //$(elements).css({color: 'gray' });
            }

            ko.bindingHandlers.masked = {
               init: function(element, valueAccessor, allBindingsAccessor) {
                  var mask = allBindingsAccessor().mask || {};
                  $(element).mask(mask);
                  ko.utils.registerEventHandler(element, 'focusout', function() {
                     var observable = valueAccessor();
                     observable($(element).val());
                  });
               }, 
               update: function (element, valueAccessor) {
                  var value = ko.utils.unwrapObservable(valueAccessor());
                  $(element).val(value);
               }
            };

            function clear() {
               self.Nome(null);
               self.Numero(null);
               self.Email(null);
               self.Focus(true);  
            }
            
            function sort() {
               self.Lista.sort(function (first, second) {
                  if (first.name.toLowerCase() > second.name.toLowerCase()) {
                     return 1;
                  } else {
                     if (second.name.toLowerCase() > first.name.toLowerCase()) {
                           return -1;
                     } else {
                           return 0;
                     }
                  }
               });
            }           
         }

         ko.applyBindings(new MyViewModel());
      </script>
<div class="div row">         
         <label> Nome: </label>
         <input type="text" data-bind="value: Nome, hasFocus: Focus, valueUpdate: 'afterkeydown'">
         <span data-bind="text: validacaoNome"></span>     

         <label> Contact Number: </label>
         <input type="text" data-bind="value: Numero, valueUpdate: 'afterkeydown'">   
            
         <label> Email: </label>
         <input type="text" data-bind="value: Email, valueUpdate: 'afterkeydown'">
         <span class="error" data-bind="validationMessage: Email"></span>
      
         <div>
            <button class="button" data-bind="click: Add"> Add </button>
            <button class="button" data-bind="click: Clear"> Clear </button>
         </div>     
      </div>

      <div class="list">
         <h2> List: </h2>
         <div data-bind = "template: { name: 'lista-template', foreach: Lista, afterRender: afterProcess }"></div>
         <script type = "text/html" id = "lista-template">
            <h3 data-bind = "text: name"></h3>
            <p> Number: <span data-bind = "text: contactNumber"></span></p>
            <p> Email: <span data-bind = "text: email"></span></p>
            <button data-bind = "click: $root.Alter"> Alter </button>
            <button data-bind = "click: $root.Remove"> Remove </button>
         </script>
      </div>         

In the name subscribe, if(value.length < 5), returns this error: Uncaught Typeerror: Cannot read Property 'length' of null. The length property is empty. Would anyone know why? Grateful for the attention!

  • Gives a console.log() in self. Name to see what returns.

  • 1

    Oops. I believe I have already located the problem. In the function that clears the fields (Clear()), they are null. Using ("") instead of (null) solves. I didn’t know there was a difference. Thanks!

1 answer

0

Include in if a condition verifying whether value is not null:

if (value && value.length < 5) {
      ↑

See working:

function MyViewModel() {
   self = this;
   var registro;

   self.Nome = ko.observable(); 
   self.validacaoNome = ko.observable();           
   
   self.Nome.subscribe(function(value) {
      if (value && value.length < 5) {
         self.validacaoNome('O nome é inválido');
      } else {
         self.validacaoNome(null);
      }
   });

   self.Numero = ko.observable();
   self.Email = ko.observable();
   self.Lista = ko.observableArray([]);
   self.Focus = ko.observable(true);

   self.Add = function() {
      if(self.Nome() && self.Numero() && self.Email()) {
         var id = Math.floor(Math.random() * (10000 + 12));
         for (var i = 0; i < self.Lista().length; i++) {
            if (self.Lista()[i].id == registro) {
               self.Lista().splice(i, 1);
            }
         }                
         self.Lista.push(
            { id: id, name: self.Nome(), contactNumber: self.Numero(), email: self.Email() }
         );
      }     
      sort();                            
      clear();                    
   }              
   
   self.Alter = function(register) {
      registro = register.id;
      self.Nome(register.name);
      self.Numero(register.contactNumber);
      self.Email(register.email);
      self.Focus(true);                
   }           

   self.Remove = function() {
      self.Lista.remove(this);
      clear();
   }

   self.Clear = function() {
      clear();
      registro = null;               
   }

   self.afterProcess = function(elements) {
      //$(elements).css({color: 'gray' });
   }

   ko.bindingHandlers.masked = {
      init: function(element, valueAccessor, allBindingsAccessor) {
         var mask = allBindingsAccessor().mask || {};
         $(element).mask(mask);
         ko.utils.registerEventHandler(element, 'focusout', function() {
            var observable = valueAccessor();
            observable($(element).val());
         });
      }, 
      update: function (element, valueAccessor) {
         var value = ko.utils.unwrapObservable(valueAccessor());
         $(element).val(value);
      }
   };

   function clear() {
      self.Nome(null);
      self.Numero(null);
      self.Email(null);
      self.Focus(true);  
   }
   
   function sort() {
      self.Lista.sort(function (first, second) {
         if (first.name.toLowerCase() > second.name.toLowerCase()) {
            return 1;
         } else {
            if (second.name.toLowerCase() > first.name.toLowerCase()) {
                  return -1;
            } else {
                  return 0;
            }
         }
      });
   }           
}

ko.applyBindings(new MyViewModel());
<script src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js'></script>
<div class="div row">         
   <label> Nome: </label>
   <input type="text" data-bind="value: Nome, hasFocus: Focus, valueUpdate: 'afterkeydown'">
   <span data-bind="text: validacaoNome"></span>     

   <label> Contact Number: </label>
   <input type="text" data-bind="value: Numero, valueUpdate: 'afterkeydown'">   
      
   <label> Email: </label>
   <input type="text" data-bind="value: Email, valueUpdate: 'afterkeydown'">
   <span class="error" data-bind="validationMessage: Email"></span>

   <div>
      <button class="button" data-bind="click: Add"> Add </button>
      <button class="button" data-bind="click: Clear"> Clear </button>
   </div>     
</div>

<div class="list">
   <h2> List: </h2>
   <div data-bind = "template: { name: 'lista-template', foreach: Lista, afterRender: afterProcess }"></div>
   <script type = "text/html" id = "lista-template">
      <h3 data-bind = "text: name"></h3>
      <p> Number: <span data-bind = "text: contactNumber"></span></p>
      <p> Email: <span data-bind = "text: email"></span></p>
      <button data-bind = "click: $root.Alter"> Alter </button>
      <button data-bind = "click: $root.Remove"> Remove </button>
   </script>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.