Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Developer Advocate
Developer Advocate
This is a searchable description of the content of a live stream recording, specifically "Episode 0 - Getting our feet wet" in the "Hands-on SAP dev with qmacro" series. There are links directly to specific highlights in the video recording. For links to annotations of other episodes, please see the "Catch the replays" section of the series blog post.

This episode, titled "Getting our feet wet", was streamed live on Fri 18 Jan 2019 and is approximately one hour in length. The stream recording is available on YouTube.

Below is a brief synopsis, and links to specific highlights - use these links to jump directly to particular places of interest in the recording, based on 'hh:mm:ss' style timestamps.

Brief synopsis

In this initial episode of the "Hands-on SAP dev with qmacro" series, we take a brief look at what using SAP's Cloud Application Programming Model in a Node.js context means for us JavaScript developers, and warm our brains up by solving some puzzles with a bit of ES6 flavoured code (with some functional aspects thrown in for good measure).

00:00:49: Shoutout to the Coffee Corner Radio podcast show.

00:02:20: A callout to just be nice to each other (which I'm sure you all are and will continue to be), and reference to the Participation Etiquette in the SAP Community Rules of Engagement.

00:03:47: A quick look at my Streamlabs setup.

00:05:02: Taking a first look at the tutorial navigator on and specifically the Create a Business Service with Note.js using Visual Studio Code tutorial.

00:07:12: Jumping ahead to the "Provide Mock Data" step in the tutorial we see that the JavaScript used is quite modern, specifically embracing many ECMAScript 6 (ES6) features, possibly less recognisable to many of us.

00:08:27: We see a similar pattern with the "Add custom logic" step later on in the tutorial, with modern JavaScript, including ES6 aspects such as destructuring and the fat arrow syntax.

00:09:37: Moving into the terminal for the rest of this episode, and bringing up a simple task for us to work on and practise our JavaScript. We'll be using the Christmas themed Advent of Code day 1 pair of puzzles to warm up our brains a little bit.

00:11:17: Diving straight into part 1 of the puzzle, looking at what's required.

00:13:07: Looking at the puzzle input (which is user-specific), and then grabbing the example input from the puzzle description itself.

00:13:37: Thinking about a good development environment for this, with quick feedback turnaround.

00:13:57: Initialising a new repo for the solution project with npm init.

00:14:05: Looking at package.json as it initially is generated.

00:15:40: Examining the 'test harness' in the form of index.js (which is referenced in package.json) - this works as a test runner for the solutions, which provides a clean function, loads the day's solvers (for parts 1 and 2) and then loads the puzzle input and tries each solution.

00:16:13: Taking a brief look at two beautiful Vim plugins Goyo and Limelight.

00:17:23: Taking a bit of a closer look at how the clean function processes the puzzle data that's read in, turning the string into a clean array of values.

00:19:05: Starting with a basic skeleton solver module with functions a and b for parts 1 and 2 of the day's puzzle, respectively.

00:20:42: Creating the initial contents of the day1.input file from the test data in the example.

00:21:21: Initial run of index.js shows that we have some work to do, not least creating a day1.js from the day0.js skeleton.

00:21:39: Using tmux to let us see the execution output of our tests as well as the contents of what we're editing. My tmux configuration is available online if you're interested, in my scripts repo.

00:22:36: Looking at the less than ideal situation of having to manually flip over from editor to runtime to test changes to the puzzle solutions.

00:23:46: The answer here is nodemon which we install directly into our project as a dev dependency, with npm i nodemon --save-dev, looking at the addition to the package.json that this caused.

00:24:27: First run of nodemon directly, using the path via the project's node_modules directory (node_modules/nodemon/bin/nodemon.js) which will automatically run the existing index.js and rerun it if anything is modified.

00:26:02: Reminding ourselves of the challenge at hand, and considering an "old fashioned" approach with a for-loop, adding one such loop to the a function (as this is part 1 from this day's pair of puzzles).

00:27:12: First, simply getting a to return the input so we can see and confirm what the function is receiving and must act upon.

00:28:02: Using a shortcut to get to my Vim configuration, so we can examine an alternative way of saving file content (with <leader>w). Check out my entire Vim config in my dotvim repo online.

00:28:45: Just going for a first attempt, in the knowledge that something with the input data isn't yet quite right. Building a simple for-loop as the basis for the solution first.

00:29:32: Talking about fold and its close relation to reduce (they're pretty much the same thing, see Fold (higher-order function)).

00:30:32: Seeing the result of the data not being quite right ... JavaScript is taking the values literally, i.e. is adding the strings together. We therefore have to turn the strings into numbers which we do with the Number class. We get the right answer now.

00:31:32: Referencing Luke Smith from whom I've learned a great deal in the *nix shell and tools configuration area.

00:32:11: Getting rid of the for-loop to embrace a modicum of functional programming, using map and also reduce. Also a quick look at the fat-arrow syntax for function definitions, not requiring curly braces to denote a block or even a return statement (if there's only a single expression to evaluate).

00:35:27: Copying in the real puzzle input, using pbpaste and rerunning the solution, which gives us the correct answer.

00:36:22: Getting ready to solve part 2 of this puzzle.

00:38:29: Examining the details of part 2.

00:40:44: Starting to build the solution to part 2 in the b function. We use the rather stylish (IMHO) xs as the parameter name for the input. "X over XS" is a phrase I remember fondly from Erik Meijer's wonderful videos on Functional Programming, F# and Haskell which you can find on YouTube here: Haskell - Functional Programming Fundamentals (Dr. Erik Meijer).

00:42:02: Switching back to the test input ready to code and test our solution for this part 2.

00:42:42: Starting to build out the b function, looking at a functional approach, and using the concept of a closure which is a super powerful idea which is implemented in many languages including of course JavaScript.

00:44:12: We create the closure in the form of an Immediately Invoked Function Expression (IIFE) which you can find details about here:

00:46:49: We now have a little function that has some memory, that we can use to check whether we've already seen a value or not. We evaluate the call to the lambda function (immediately invoke it) and capture the returned value in the seen constant - this value is actually the function that is defined, taking a single parameter x, directly following the return statement:

const seen = (() => {
const values = []
return x => {
if (values.indexOf(x) > -1) {
return true
} else {
return false

00:50:12: We try this out with the following test invocation: return [1, 2, 3, 2, 1].map(seen) which gives us, correctly, [ false, false, false, true, true ].

00:51:02: Now we start to build out the latter part of this solution, that uses seen. Starting with an initial frequency of 0, iterating over the list of frequencies with a view to having to wrap around in case the list is exhausted before we get to the solution (which it will be) - modulo arithmetic is required here.

00:52:57: Now we bring in the real input again, and run the solution upon it, and the answer it returns is the correct one (hurray). Adding a bit of code to count how many frequency changes the solution must iterate through shows a value of more than 139k!