0

I'm learning OOJS and I want to use pattern getters and setters (for study), but I don't understand why my test doesn't catch the error when I use the set. If I use without set, just only a method, it works.

In my test the empty field is validated and this is not expected, the correct thing is to return the empty field error

My class:

export default class Category {
  constructor(name) {
    this._name = name;
  }

  set name(name) {
    if (isEmpty(name) || isNull(name))
      throw new Error(`category field needs to be filled`);
    this._name = name;
  }
  get name() {
    return this._name;
  }

}

categoryDAO

import Category from "../models/Category.js";

export default class CategoryDAO {
  constructor() {
    this._list = [];
  }
  add(category) {
    if (!(category instanceof Category)) {
      throw new Error("the object is not of type category");
    }

    if (this._list.some((c) => c.name === category.name)) {
      throw new Error("category has been created");
    }
    this._list.push(category);
  }
}

test

try {
  const categoryDAO = new CategoryDAO();
  const category1 = new Category("Devops");
  const category2 = new Category("Devops");
  categoryDAO.add(category1);
  categoryDAO.add(category2);
  console.log(`saved ${category1.name}`);
  console.log(`saved ${category2.name}`);
} catch (err) {
  console.log(`WRG ${err}`);
}

try {
  const categoryDAO = new CategoryDAO();
  const category1 = new Category(" ");
  categoryDAO.add(category1);
  console.log(`saved ${category1.name}`);
} catch (err) {
  console.log(`WRG ${err}`);
}

validate.js

export const mailFormat = /^([\w-]\.?)+@([\w-]+\.)+([A-Za-z]{2,4})+$/g;

export const notEmpty = (value) => (value === " " ? false : true);

export const isEmpty = (value) => !notEmpty(value);

export const isNull = (value) => value === null;

export const maxLength = (length) => (value) => value.length < length;

Thanks for any help

Laura
  • 99
  • 9
  • Did you write the `isEmpty` and `isNull` function yourself? If so: please share these as well. – Mathyn Jul 11 '20 at 22:28
  • One, or both, of those functions is probably not doing what you expect and should be easy enough to debug – charlietfl Jul 11 '20 at 22:34

2 Answers2

0

Your constructor sets the _name without using your set function, therefore your validation is not fired. Try this constructor instead:

export default class Category {
  constructor(name) {
    this.name = name;
  }
  [...]
}

I also think you can improve your "isEmpty()" and the "isNull()" function. Take a look in this thread.

Here is a full fiddle of your application.

Amacado
  • 630
  • 5
  • 20
  • Hi, amacado, even removing the space, the test does not return an error (: – Laura Jul 11 '20 at 22:21
  • @Laura i updated my answer and provided a working fiddle example. – Amacado Jul 11 '20 at 22:47
  • Amocado, thanks for your anwer. How can i use the private attribute in my contructor so that validation is done? I couldn't put it in my head. – Laura Jul 11 '20 at 22:48
  • with using the underline – Laura Jul 11 '20 at 22:51
  • You dont. If you want the validation to be executed, you are not allowed to set the private variable `_name` at any other point then after the validation is done in your `set name()` method. – Amacado Jul 11 '20 at 22:54
  • Amocado, thank you very much, but I thought that way because I saw get and set patterns this way but something with either my dao class or my test couldn't read the validations: https://coryrylan.com/blog/javascript-es6-class-syntax – Laura Jul 12 '20 at 00:14
0

The reason why you don't get the error when you pass an empty string is because you create the name using the constructor. if you want to verify the input using set you should pass the name to set here is an example

class Category {
  constructor(name) {
    this._name = name;
  }
  set name(name) {
    if (name.length==0 )
      throw new Error(`category field needs to be filled`);
    this._name = name;
  }
  get name() {
    return this._name;
  }

}

const category1 = new Category();
category1.name=""
Sven.hig
  • 4,449
  • 2
  • 8
  • 18
  • This would work, but leads to inconsistent data. The idea of a validator is that the data beeing validated. Your solution does not execute the validator when the object is initialised through the constructor and therefore allows `name` to be empty. This is correct "by code" but not "by logical expression" – Amacado Jul 11 '20 at 22:58
  • Like i mentioned above this is only an example to answer OP's question into why there `set` doesn't throw an error – Sven.hig Jul 11 '20 at 23:01
  • and by the way i looked at your jsfiddle all what you have done is change the name in the constructor so that it gets passed to `set ` and so I am not sure what's the major difference between your jsfiddle and my answer, here is my [jsfiddle](https://jsfiddle.net/sven07/9srw0gnf/) will produce the same result – Sven.hig Jul 11 '20 at 23:24
  • I never said that your answer is wrong nor wanted to offend you. We just had different approches: While you are rewriting the testing routine, i have rewritten the code to fullfill the existing test. Just two different approches :) – Amacado Jul 11 '20 at 23:32