DEV Community

Discussion on: Transducers in javascript

Collapse
 
vonheikemen profile image
Heiker • Edited

Inspired by this post, that's about getting data from your dev.to dashboard using the browser's devtools. I'm going to do the same but with transducers.

The original code transforms NodeList to an array in order to use map and filter, but we don't need to do that.

If you're trying this, make sure you have all the utility functions in scope.

// Common utilities

var ensure_number = (value) => 
  Number.isNaN(value) ? 0 : value;

var get_text = (element) => (query) =>
  element.querySelector(query).innerText;

// Useful callbacks

var get_data = function(story) {
  const text = get_text(story);
  return {
    published: new Date(story.querySelector('time').dateTime),
    reactions: Number(text('[title="Reactions"]')),
    comments: Number(text('[title="Comments"]')),
    views: Number(text('[title="Views"]')),
  };
};

var published_2020 = function(story) {
  return story.published.getFullYear() === 2020;
}

var add_stats = function(state, value) {
  return {
    reactions: state.reactions + value.reactions,
    comments: state.comments + value.comments,
    views: state.views + ensure_number(value.views)
  };
};

// Transducer stuff

var stats = {
  reactions: 0,
  comments: 0,
  views: 0,
};

var transducer = compose(
  map(get_data),
  filter(published_2020)
);

var stories = document.querySelectorAll(
  '.dashboard-story:not(.story-unpublished)'
);

transduce(add_stats, stats, transducer, stories);
Enter fullscreen mode Exit fullscreen mode

The full example is here.