Locked learning resources

Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Porting the Shipping Label Script

Porting the Shipping Label Script

Marta’s shop tools are moving to JavaScript, so in this project, you ported most of her Python script, and for order 1042, the port prints exactly Python’s label. The remote-area surcharge and the gift check are left for the exercise.

  • The rates table keeps its home country in a variable. A bare key in a JavaScript literal is the key’s own name, so the variable goes in brackets: [HOME_COUNTRY]: 3.2.
  • The tracked countries become a Set built from an array, new Set(["US", "CA", "AU"]). In JavaScript, braces make an object, so Python’s set literal would stop the file with a syntax error.
  • The paste goes between backticks: a template literal spans lines, like Python’s triple quotes. Unlike them, a backtick inside the paste would end it, and ${ would start code. JSON.parse() turns the text into an object.
  • Iris ticked “same as billing”, so the shipping address is null. Python’s or is || in JavaScript. The port uses ?? instead: it steps past only null and undefined, so Iris gets the Leeds billing address.
  • Order 1042 has no customer block, so the phone reads it with ?., then a default, "no phone": order.customer?.phone ?? "no phone". Without ?., reading phone from undefined would raise a TypeError and stop the script.
  • The country is a fixed key, so it’s read with a dot. The rate’s key comes from the data, so it goes in brackets, with the rest of the world rate as the default: RATES[country] ?? RATES.ROW. Iris’s order gets 3.2, as in Python. In JavaScript, the table needed brackets to make "GB" a key. RATES.country would look for a key called country, and Iris would pay 16.5, with no warning.
  • The tags become a Set, which drops the repeated "gift". The label is an object literal with Python’s keys. For tracked, the Set’s .has() method answers the question: Iris’s order isn’t tracked. JavaScript’s in operator asks about an object’s properties, not a Set’s members, so it would say false even for the US.
  • The parcels are the line items, counted with .length where Python uses len(). Like len(), .length counts the line items, not the three notebooks in them, so the label gets two parcels.
  • The insured value keeps Iris’s 0 with ??. ||, like Python’s or, would replace it with 50, the cover she turned down. The tags go in as an array, spread out of the Set and sorted, fragile then gift: [...tags].toSorted(). Left as a Set, it would come out empty, {}, where Python’s json.dumps() refuses it.
  • The print line becomes console.log(), with JSON.stringify() where json.dumps() was. With no keyword arguments, the indent goes third, after null, which says “no replacer”: JSON.stringify(label, null, 2). A 2 in second place would print the label on one line.

Here’s the port, shipping-label.js, with the surcharge and the gift check still to come:

Language: JavaScript
const HOME_COUNTRY = "GB";
const RATES = {
  [HOME_COUNTRY]: 3.2,
  IE: 7.5,
  DE: 8.9,
  US: 14.5,
  ROW: 16.5,
};
const TRACKED_COUNTRIES = new Set(["US", "CA", "AU"]);

const ORDER_TEXT = `{
  "id": 1042,
  "billing_address": {
    "name": "Iris Okafor",
    "street": "12 Marsh Lane",
    "city": "Leeds",
    "postcode": "LS6 2QA",
    "country": "GB"
  },
  "shipping_address": null,
  "insured_value": 0,
  "line_items": [
    { "sku": "A5-DOT", "qty": 2 },
    { "sku": "A6-LINED", "qty": 1 }
  ],
  "tags": ["gift", "fragile", "gift"],
  "total": 46.0
}`;

const order = JSON.parse(ORDER_TEXT);
const address = order.shipping_address ?? order.billing_address;
const phone = order.customer?.phone ?? "no phone";
const country = address.country;
const postage = RATES[country] ?? RATES.ROW;
const tags = new Set(order.tags);

const label = {
  order: order.id,
  to: address,
  phone: phone,
  postage: postage,
  tracked: TRACKED_COUNTRIES.has(country),
  parcels: order.line_items.length,
  insured_value: order.insured_value ?? 50,
  tags: [...tags].toSorted(),
};
console.log(JSON.stringify(label, null, 2));

Locked learning resources

Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

Locked learning resources

The full lesson is for members only. Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

00:00 Marta’s shop tools are moving to JavaScript. You’ll port most of her Python script, and for order 1042, print exactly Python’s label. The script reads its tables, parses the order, and picks the address and phone.

00:16 It looks up the postage, builds the label and prints it as JSON. The remote-area surcharge and the gift check are left for the exercise. The rates table keeps its home country in a variable.

00:31 A bare key in a JavaScript literal is the key’s own name, so the variable goes in brackets.

00:39 The tracked countries become a Set, built from an array. In JavaScript, braces make an object, so Python’s set literal would stop the file with a syntax error.

00:52 The paste goes between backticks: a template literal spans lines, like Python’s triple quotes. Unlike them, a backtick inside the paste would end it, and ${ would start code.

01:05 JSON.parse() turns the text into an object.

01:11 Iris ticked same as billing, so the shipping address is null. Python’s or is || in JavaScript. The port uses the nullish coalescing operator (??) instead.

01:24 It steps past only null and undefined, so Iris gets the Leeds billing address.

01:30 Order 1042 has no customer block, so the phone uses optional chaining (?.), then a default: no phone. Without optional chaining (?.), reading phone from undefined would raise a TypeError and stop the script.

01:45 The country is a fixed key, read with a dot. The rate’s key comes from the data, so it’s in brackets, with the rest of the world rate as the default. What postage does Iris’s order get?

02:00 Your turn: pause the video and predict.

02:08 It’s three point two, as in Python. In JavaScript, the table needed brackets to make GB a key. RATES.country would look for a key called country: Iris would pay sixteen point five, with no warning.

02:26 The tags become a Set, which drops the repeated gift. The label is an object literal with Python’s keys, and the first four values carry across. For tracked, the Set’s .has() method answers the question: Iris’s order isn’t tracked.

02:43 JavaScript’s in operator asks about properties, not a Set’s members, so it would say false even for the US.

02:53 The parcels are the line items, and .length counts them the way len() does in Python. It counts the items, not the three notebooks in them, so the label gets two parcels.

03:06 The insured value keeps Iris’s zero with the nullish coalescing operator (??). ||, like Python’s or, would replace it with fifty, cover she turned down.

03:18 The tags go in as an array, spread out of the Set and sorted: fragile, then gift. Left as a Set, it would come out empty, where Python’s json.dumps() refuses it.

03:32 The print line becomes console.log(), with JSON.stringify() where json.dumps() was. With no keyword arguments, the indent goes third, after null, which says no replacer.

03:44 A 2 in second place would print the label on one line.

03:50 The whole port, next to the Python: the tables, order, address and phone, postage, label and print.

04:00 node --check reads the file and says nothing: no syntax errors. Run it, and JavaScript prints the label. It matches Python’s, line for line. The rule: port each line the JavaScript way, then check that the output matches.

04:20 Brackets for keys from data, a default for what might be missing, and arrays in JSON. Next up: the exercise Finish the Shipping Label. You’ll add the price for orders that aren’t gifts and the remote-area surcharge, then print the labels for 1042 and 1043 to match Python’s.

Become a Member to join the conversation.