NSWI142: Web Applications

8. JavaScript Introduction

Jáchym Bártík, KSI
jachym.bartik@matfyz.cuni.cz

Preliminaries

Please read this section at least one day prior to the seminar. This section outlines what you are expected to know, be able to do, or have prepared in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.

Preliminaries

Before the start of the practical, you should be able to:

  • Write hello world in JavaScript.
  • Use basic JavaScript syntax (variables, functions, conditionals, loops).
  • Run JavaScript in the browser console.
  • Explain the difference between JavaScript and Java.

If you didn't attend the lecture (or just want to refresh your memory), please review this short JavaScript Crash Course. Note: This is a work in progress, more chapters will be added later.

Preliminaries software

This slide applies to you only if you plan to use your own computer for the practical.

JavaScript can be run directly in the web browser. However, in this practical, we will be working with filesystem so please install JavaScript runtime such as Node.js:

  • If you have a package manager, just use it. The package is usually called nodejs.
  • Otherwise, visit the Node.js download page. Make sure to install the LTS version.
  • After the installation, create a simple JavaScript file
    
              console.log("Hello, World!");
            
    and run it using
    
              node script.js
            
  • If you use VS Code or WebStorm as your IDE, the JavaScript support is already built-in.

Agenda

  • JavaScript Introduction
  • Exercise: Rectangle
  • Files and JSON
  • Exercise: JSON query language
  • Exercise: JSON query script

JavaScript Introduction

You can run JavaScript locally using Node.js - just run


        node script.js
      
Node.js is available at lab computers and also at Webik.

Or use online sandbox (e.g., jsfiddle.net).

Output

Main output depends on a runtime environment of choice:

  • Node.js: process.stdout.write(' ... ') / HTTP
  • Browser: interaction with DOM

We can utilize console.log in both. It is designed as a log function and performs formatting. There are other log levels: console.warn, console.error, ...

JavaScript Language

Since you have read the Crash Course, you already know everything you need!

Any questions?

Exercise: Rectangle

Create a function that given the size of a rectangle (width, height) renders the rectangle to output using ASCII art (see example bellow). Test the function by calling it several times and properly handle all edge cases (e.g., lengths 0, 1, and 2).
Mind code decomposition!
Do not read from standard input, hard-code the input values in your code.

Example output for values (5, 3):


    *---*
    |...|
    *---*
    

If you are done, try different environments (Browser, Node.js, online tool).

Files and JSON

Use the fs module to read and write to files:


      import fs from 'node:fs';

      const content = fs.readFileSync('path/to/input.json', 'utf-8');
      fs.writeFileSync('path/to/output.json', content);
    

Use the JSON object to transform JSON strings:


      const object = JSON.parse('{ "key": "value" }');
      object; // { key: 'value' }

      const string = JSON.stringify([ 'a', 'b' ]);
      string; // '["a","b"]'
    

Exercise: JSON query language

Create a function that, given a pattern and an array of input objects, will return only those objects that match the pattern.

Load the input objects from a JSON file. The file path can be hardcoded in your script. You can use this example input.

Pattern

The pattern is an object where each key-value pair specifies a required property. The value can be either a primitive type, a function, or another object. For each such property, you have to first find a corresponding property in the input object (if there is none, the input is filtered out). Then decide based on the pattern value:

  • A primitive type - it has to be strictly equal to the input value.
  • A function - pass to it the input value and check whether it returns a truthy value.
  • An object - check that the input value is also an object and recursively apply the same rules.

Tests

The example input contains an array of 100 objects so you can test your solution. Here are some example patterns and their expected output lengths:


        { company: x => x.length === 9 }
      
(15)

        
        { account: { balance: x => parseFloat(x.replace(/[^\d.]/g, '')) >= 3469 } }
      
(13)


        { isActive: true, person: { address: { zip: x => x <= 930 || x >= 9300 } } }
      
(9)


        { contact: x => x.email && x.phone }
      
(8)

Continue to the next slide once you are done.

Exercise: JSON query script

Create a script that, given a template and an array of input objects, will return only those objects that match the template.

Pass both arguments as CLI arguments. The first one should be a JSON string (the template), the second one should be a path to a JSON file (which contains the array of inputs).

  • If you use Node.js, the CLI arguments are available in the global process.argv array. However, you have to skip the first two elements (paths to the executable and the script).
  • If you use some other environment, hardcode the template and content of the input file.

Template

The template is a JSON object with key-value pairs. Use it to build a pattern which can be passed to the function from the previous exercise. Decide based on the template value:

  • A boolean - cast the input value to boolean and compare them.
  • A number - cast the input value to number and check that the template number is smaller or equal.
  • A string - cast the input value to string and check that the template string is its substring.
  • An object - check that the input value is also an object and recursively apply the same rules.

Tests

Use the same input as before. Here are some example templates and their expected output lengths:


        { "company": "X" }
      
(15)

        
        { "person": { "about": "Lorem" }, "account": { "balance": "$3" } }
      
(13)


        { "isActive": true, "person": { "firstName": "a", "address": { "zip": 8421 } } }
      
(9)


        { "contact": { "email": "", "phone": "" } }
      
(8)

Continue to the next slide once you are done.

Bonus: Array template

Extend the previous script to support arrays in the template.
If the template value is an array, the input value needs to be matched by at least one element of the array. This works for both primitive values and objects (and for the whole template, too). For example:


      const input = { id: 'Joe' };
      // matching templates:
      { id: [ 'Joe', 'Jane' ] };
      [ { id: 'Joe' } ];
      [ { x: 'y' }, {} ];
      // non-matching templates:
      { id: [] };
      [];
    

Upload the script to Webik as ~/public_html/js-query.js. Make sure to use this exact name so we can find it by an automated script.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.