0

I am creating a factory and trying to put some methods onto it. I am testing with simple console.logs. The method that logs a string works (logTitle), the one that references a boolean (logCompleated) (which i later want to change with an updated method that will toggle compleated from true to false and back) does not work. I get "arrayFunctions.js:20 Uncaught ReferenceError: compleated is not defined" comments in the code to highlight problem. Thanks in advance.

const todoFactory = (
  title,
  project = "",
  dueDate = "",
  priority = "",
  notes = ""
) => {
 
  return {
    title,
    project,
    dueDate,
    priority,
    notes,
    compleated: false,
    logTitle: () => console.log(title), //works
    logCompleated: () => console.log(compleated), //arrayFunctions.js:20 Uncaught ReferenceError: compleated is not defined
  };
};
suubcity
  • 21
  • 2

2 Answers2

1

That title works may be misleading you. That function, even used as a method of your TODO object, is not making reference to the title property of the object you've created. Instead, it refers to the parameter of the factory function. You can check this by doing something like return {title: title + 'foobar', project,...}. When you call myTodo.logTitle() you will log only the value you supplied as a parameter.

You can fix this by adding compleated (note: Usual English spelling is "completed") as a local variable before the return.

const todoFactory = (
  title,
  project = "",
  dueDate = "",
  priority = "",
  notes = ""
) => {

  return {
    title,
    project,
    dueDate,
    priority,
    notes,
    compleated: false,
    logTitle: () => console.log(title),
    logCompleated: () => console.log(compleated),
  };
};

const todo = todoFactory('foo')

todo.logCompleated()

Or you can make it a function expression (using the function keyword rather than an arrow) and use this.compleated in the body. Arrow functions have a different behavior regarding this.

const todoFactory = (
  title,
  project = "",
  dueDate = "",
  priority = "",
  notes = ""
) => {
  const compleated = false
  return {
    title,
    project,
    dueDate,
    priority,
    notes,
    compleated,
    logTitle: function() {console.log(this.title)},
    logCompleated: function() {console.log(compleated)},
  };
};

const todo = todoFactory('foo')

todo.logCompleated()
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • scott is there a good resource you can recommend so I can understand this better? Or just a google search term I can type in. :-) thanks a lot for you answer! – suubcity Sep 15 '20 at 17:50
  • @suubcity [See this older question](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable) – Pointy Sep 15 '20 at 17:54
  • It's simply a matter of [scoping](https://developer.mozilla.org/en-US/docs/Glossary/Scope) in JS. The object you return has reference to a [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) that includes the parameters and local variables in your factory function. You can also learn that [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) do not have their own bindings to `this`. – Scott Sauyet Sep 15 '20 at 17:55
0

Use a regular function and inside it use this.compleated

suubcity
  • 21
  • 2