Search code examples
javascriptobject-literal

Creating object literal fails in observable notebook


I'm trying to run this simple code snippet from O'Reilly's "Learning React" book in an Observable notebook (https://observablehq.com/).

It works if I run it in the Chrome console (I can define the object and then run tahoe.print()), but if I try to run it in Observable I get SyntaxError: Unexpected Token when running the cell.

Is there something strange about Observable that prevents me from creating object literals like this?

tahoe = {
  resorts: ["Kirkwood","Squaw","Alpine"],
  print: function(delay=1000) {
    setTimeout(() => {
      console.log(this.resorts.join(", "))
    }, delay)
  }
}

Here's the notebook with the code: https://observablehq.com/@jritch/simple-snippet-breaks-in-observable


Solution

  • Blex pointed out that to get this to work you need to wrap the object in parentheses:

    tahoe = ({
      resorts: ["Kirkwood","Squaw","Alpine"],
      print: function(delay=1000) {
        setTimeout(() => {
          console.log(this.resorts.join(", "))
        }, delay)
      }
    })
    

    Working snippet.

    For a fuller explanation of why this is, see this blogpost that outlines the differences between Observable and vanilla javascript:

    Statements need curly braces, and return (or yield). A cell body can be a simple expression, such as a number or string literal, or a function call. But sometimes you want statements, such as for loops. For that you’ll need curly braces, and a return statement to give the cell a value. Think of a cell as a function, except the function has no arguments. For the same reason, you’ll need to wrap object literals in parentheses, or use a block statement with a return.

    There's also a (somewhat difficult to see) magic wand widget that comes up beside the play button icon for the cell, that will automatically fix this issue if you click it:

    https://i.imgur.com/uf5H1LA.png