Chapter 12. Implementing Unidirectional Functional Associations with Plain JavaScript

Table of Contents

1. Implementing Single-Valued Reference Properties with Plain JavaScript
2. Make a JavaScript Data Model
3. New issues
4. Write the Model Code
4.1. Summary
4.2. Encode each class of the JavaScript data model as a constructor function
4.3. Encode the property checks
4.4. Encode the property setters
4.5. Implement a deletion policy
4.6. Serialization and De-Serialization
5. The View and Controller Layers
5.1. Initialize the app
5.2. Show information about associated objects in the List Objects use case
5.3. Allow selecting associated objects in the create and update use cases
6. Quiz Questions
6.1. Question 1: JavaScript data model

The three example apps that we have discussed in previous chapters, the minimal app,the validation app, and the enumeration app, have been limited to managing the data of one object type only. A real app, however, has to manage the data of several object types, which are typically related to each other in various ways. In particular, there may be associations and subtype (inheritance) relationships between object types. Handling associations and subtype relationships are advanced issues in software application engineering. They are often not sufficiently discussed in software development text books and not well supported by application development frameworks. In this part of the tutorial, we show how to deal with unidirectional associations, while bidirectional associations and subtype relationships are covered in parts 5 and 6.

We adopt the approach of model-based development, which provides a general methodology for engineering all kinds of artifacts, including data management apps. For being able to understand this tutorial, you need to understand the underlying concepts and theory. Either you first read the theory chapter on reference properties and associations, before you continue to read this tutorial chapter, or you start reading this tutorial chapter and consult the theory chapter only on demand, e.g., when you stumble upon a term that you don't know.

A unidirectional functional association is either one-to-one or many-to-one. In both cases such an association is represented, or implemented, with the help of a single-valued reference property.

In this chapter of our tutorial, we show

  1. how to derive a plain JavaScript data model from an association-free information design model with single-valued reference properties representing unidirectional functional associations,

  2. how to encode the data model in the form of plain JavaScript model classes,

  3. how to write the view and controller code based on the model code.

1. Implementing Single-Valued Reference Properties with Plain JavaScript

A single-valued reference property, such as the property publisher of the object type Book, allows storing internal references to objects of another type, such as Publisher. When creating a new object, the constructor function needs to have a parameter for allowing to assign a suitable value to the reference property. In a typed programming language, such as Java, we would have to take a decision if this value is expected to be an internal object reference or an ID reference. In JavaScript, however, we can take a more flexible approach and allow using either of them, as shown in the following exmple:

function Book( slots) {
  // set the default values for the parameter-free default constructor
  ...
  this.publisher = null;  // optional reference property
  ...
  // constructor invocation with a slots argument
  if (arguments.length > 0) {
    ...
    if (slots.publisher) this.setPublisher( slots.publisher);
    else if (slots.publisherIdRef) this.setPublisher( slots.publisherIdRef);
    ...
  }
}

Notice that, for flexibility, the constructor parameter slots may contain either a publisher slot representing an (internal) JavaScript object reference or a publisherIdRef slot representing an (external) ID reference (or foreign key). We handle the resulting ambiguity in the property setter by checking the type of the argument as shown in the following code fragment:

Book.prototype.setPublisher = function (p) {
  ...
  var publisherIdRef = "";
  if (typeof(p) !== "object") {  // ID reference
    publisherIdRef = p;
  } else {                       // object reference
    publisherIdRef = p.name;
  }
}

Notice that the name of a publisher is used as an ID reference (or foreign key), since this is the standard identifier (or primary key) of the Publisher class.