Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

index.js

Michael Nutt edited this page Mar 23, 2018 · 2 revisions

Path: app/js/index.js

The app/js/index.js file contains the business logic for your app, and appears to the user in the JavaScript pane.

Dependencies

At the very top of the file you will import your dependencies, for example:

import StudioApp from 'studio-app';

This creates a StudioApp constant variable that references the studio-app module. In this case, studio-app is an npm package declared in package.json. Dependencies can either be npm packages that implement CommonJS or ES6 modules, or they can be relative references to other javascript files in your repository. For example:

import MyUtils from './my-utils';

This would find a relative ./my-utils at app/js/my-utils.js. Note that my-utils.js needs to declare an ES6 export with export default function() { ... } or export default const ..., etc.

When the MDK bundles the app, your app/js/index.js gets copied to dist/index.js, and everything it imports gets packaged into dist/vendor.js. Since browsers can't parse import statements yet, the import statements in index.js get rewritten:

import CD from 'cropduster';
import StudioApp from 'studio-app';

turns into:

const CD = studioDependencies['cropduster'];
const StudioApp = studioDependencies['studio-app'];

StudioApp

Every MDK app includes StudioApp as one of its dependencies, and all apps you create will inherit from this class. The source of StudioApp is commented and not too long and available here.

When your app extends StudioApp, there are only two required methods to implement: constructor() and render().

constructor()

class MyApp extends StudioApp {
  constructor() {
    super();
    this.name = this.param('name', { required: true });
  }
}

The constructor() method is called when your app is instantiated. You can pass arguments to it from index.html if you want, but you don't have to. You must call super() at the beginning if you plan to use anything involving this. In the example above, we use the constructor to set a parameter to an instance variable.

render()

This method handles actually running your business logic and making any changes to the page. It gets called with no arguments. You can either put all of your logic in render(), or you can split up your logic into different methods and call them from render().

Helper methods supported by StudioApp

this.options

This is a helper for the MI.options object. This object is injected by Studio when the user saves the app. The MDK GUI Preview tab injects preview data for MI.options.

this.fields

Each field specified in the fields list in manifest.yml. It is an object with the field name as the key. For example:

# manifest.yml
fields:
  - name: firstName
    label: First name
    type: text

If the user types 'robert' into the field, when your app renders:

this.fields.firstName
// => { name: 'firstName', label: 'First name', type: 'text', value: 'robert' }

Fields are also available via an array from this.options.fields.

this.tags

This list is deserialized from the mi-attibutes element in index.html. Each object in the list includes the Tag properties, as well as an element property returning the DOM element of the Tag. Example:

this.tags[0]
// => { element: [native DOM element], id:"4862283035564132", type:"text", text:"[weather-temp]", label:"", locked: false, imageUrl: "", 
toolName: "temperature", dataType: "dynamic", autoresize: false, classNames: "", childLayout: "absolute", previewText: "75° F", sourceIndex: 0, fallbackText: "", toolProperties: { includeSymbol: true }, minimumFontSize: 0, advancedOptions {}, top: 150, left: 0, color:"#000000", width: 251, borderRadius: 0, borderColor:"#000000", borderStyle: "none", borderWidth: 0, boxSizing: "border-box", height: 40, marginTop: 0, marginLeft: 0, marginBottom: 0 }

Studio apps can have nested tags, and this.tags only includes the top-level tags. To get a flat list of all Tags in the app, use this.allTags.

this.waitForImageAssets()

Calls CD.waitForAsset() on all images on the page, including those specified as backgrounds as well as <img src="..."> images. While the rendering engine will wait for images present in the page on domready, any images you add afterwards need to be explicitly waited on, and this function will do that.

this.replaceTokens(tags, data)

Movable Ink uses the [token] convention to denote placeholder tokens. This function takes an array of tags (for example, this.tags), finds the tokens inside them, and replaces each token with the value from the data object.

this.error(msg)

The rendering platform will log an error and return the user's specified fallback image.

this.param(key, opts={})

Helper method for getting query params off of the page URL. The key is the key of the query param, and opts can include one of a few things:

  • this.param('foo', { defaultValue: 'bar' }) will look for the query param foo and return it if present, if not, it will return 'bar'.
  • this.param('foo', { defaultValue: () => 3 + 3 + '' }) will look return the query param foo if present, and otherwise run the defaultValue function and return 6.
  • this.param('foo', { required: true }) will return the query param foo if present, and otherwise throw an error and display the fallback image.