newbie question: setting initial variable, iterating, and 'printing' values in Observable

Hi All,

Another newbie JS question concerning differences in Observable vs. ‘traditional’ JavaScript…

I’m following along the tutorials from learnjsdata, and currently am working on the section on iterating.

The example defines data, then defines count as a variable with the initial value of 0:

var data = [
  {"city":"seattle", "state":"WA", "population":652405, "land_area":83.9},
  {"city":"new york", "state":"NY", "population":8405837, "land_area":302.6},
  {"city":"boston", "state":"MA", "population":645966, "land_area":48.3},
  {"city":"kansas city", "state":"MO", "population":467007, "land_area":315}
];
var count = 0;

data.forEach(function(d) {
  count += 1;
});

console.log(count);

If I try this in Observable without first creating a function, I get an error on var about an unexpected token. If I try to set count in a separate cell, I get an error about assignment to a constant variable. If I transform this into a function in a manner similar to an example in Mike’s tutorial on flat arrays, I get a function, but I can’t seem to get it to return an actual value. [That is, the example suggests I use console.log(data.length);, but the console.log() function doesn’t seem to be relevant in Observable.]

I see that functions can return values, such as in Mike’s Introduction to Asynchronous Iteration, where he uses let instead of var and then defines another const, but I can’t see how to make it work with this tutorial. The method of defining and mutating variables with functions in Observable still confuses me a bit. :confused:

How best to understand how to add in a variable to a function and when to separate it? And how to ‘print’ the value for a function in Observable?

Thanks in advance for your help!

Hi @aaronkyle,

And how to ‘print’ the value for a function in Observable?

I’ll only address this question, since the other question is a bit too broad (you may want to try the tutorial you linked in ordinary JS+HTML before trying to convert it to Observable!).

console.log is just as useful on Observable as anywhere else, but to make use of it, you need to have your browser console visible. (ctrl+shift+j (macOS: cmd+alt+j) on chrome, ctrl+shift+k (macOS: cmd+alt+j) on firefox).

To get the value to display on the page, you should use a return statement at the end of the cell.

Now here are some comments on your notebook and on cells vs functions:

When you write an Observable cell you should make sure that it’s a single expression or a block. Have a look at the examples in “Introduction to code”. Roughly speaking, all the cells are converted to functions which are then evaluated in a specific order to give the “output cell” above the source code. Most of the time, this means that if you have multiple expressions, you should wrap them up in curly braces { }:

// wrap this in a block
{
  var count = 0;

  data.forEach(function(d) {
    // count1 wasn't declared so you got an error -- I think you meant count
    count += 1;
  });

  console.log(count); // check the browser console!
  // a return statement makes this block a function with output
  return count;
}

If you want you can name this block:

namedCell = { ... }

or abstract it into a function:

function functionCell(inputs) { ... }

When you do the latter, note that you’re really writing a cell which returns a function; this should be contrasted with ordinary cells which typically return data (though it’s really no different, the above is equivalent to writing:

functionCell = {
  return function functionCell(inputs) { ... };
}

).

1 Like

Thanks for this, @bgchen. I’ll re-cap to ensure that I have got it:

console.log(count); will print a return value to the browser console (thanks for the key commands for how to open it!). If this were normal HTML, it prints to the HTML container. the page would appear blank but the value similarly visible in the browser console.

return count; can be used both with console.log(count); or independently of it, and will return the value for the cell. If the cell is named, the value can then be ‘called’ by referencing the named cell elsewhere.

Thus, once could also re-write the tutorial example as follows for it to ‘print’ the value (‘return’ the value to the cell, rather than directing it to the console):

{
  var count = 0;

  data.forEach(function(d) {
    // count1 wasn't declared so you got an error -- I think you meant count
    count += 1;
  });

  return count;
}

As for the last bit on writing a cell that returns a function - I still don’t know that I get how this works. If I write a function that returns a function, which itself is meant to calculate a value, how to I get that value? For example this is the example code as a function, but I using return count; within that second, nested function still won’t print / return the value to the cell:

function count(values) {
  var count = 0;

data.forEach(function(d) {
  count += 1;
});

  return count;
}

Is there a way to get at the value from an “abstracted” function?

I think the function “count” that you defined may not be quite what you want:

// values wasn't used anywhere inside! 
// Maybe you mean this?
function count(data) {
  var count = 0;

data.forEach(function(d) {
  count += 1;
});

  return count;
}

Is there a way to get at the value from an “abstracted” function?

Absolutely, just call the function on some data in another cell:

// this cell is just a single expression
count(data)

or

// this cell is a block 
{
  return count(data);
}

Or you can use it in other code like this:

{
  // data, data2, data3 all defined somewhere here
  // ...
  const countOfData = count(data);
  const countOfData2 = count(data2);
  const countOfData3 = count(data3);

  // now do stuff with the variables countOfData, countOfData2, and countOfData3
  // ...
}
2 Likes

HUGE thanks @bgchen!!! Your explanations are so clear and helpful, and you’re more than generous in taking the time to reply. I hope that other like me first starting to learn about data manipulation and JavaScript eventually also find this useful (so that the benefits of your time extend far beyond our exchange here).

I credit Observable, you, and other members this community with making JS accessible to those of us without any sort of formal training. Learning all of this from online tutorials is tough. I have an analogy from when I was first learning Linux and asking questions like “How do I turn on the computer?” Answers were all very technical: “the kernal does this, then these jobs run, these settings are referenced, etc. etc.”… when the answer I was often looking for was something like “Look for the round button with the circle symbol on the front, press it, and wait till it turns green”. In other words, sometime one’s understanding of the very basics is assumed, and therefore no one talks about them.

Your examples and expositions are right on target for those at my level. Thank you again for having the patience to teach, and for being so willing to help!

Sincerely,

Aaron

2 Likes