Manual Reference Source Test

Clinical6-SDK-JS

Build Status Documentation Status

API Internal Documentation

The Clinical6 SDK is a JavaScript library used to access the Clinical6 API.


Configuration

This is a client library that depends on already having a working Clinical6 endpoint. You can quickly verify your endpoint using the following command:

curl -H "Content-Type: application/json" -X POST -d '{"device":{"udid":"sampleid","technology":"ios","push_id":"abc","app_version":"1.0"}}' https://mysite.captivereach.com/api/mobile_users/sign_in_guest

The curl command above should return an alphanumeric auth_token in its response.

Getting Started

Installation

To install for a mobile or web application use the following

npm install clinical6 --save

Contribution

# Pre-project setup: Verify latest version of NPM is installed & clone the source code
npm --version
git clone https://github.com/parallel-6/Clinical6-SDK-JS.git

# Install dev dependencies
cd Clinical6-SDK-JS
npm install

Module Loading

This SDK can be used in the browser via a global variable.

<script src="dist/clinical6.js"></script>
<script>
  const clinical6 = new C6.Clinical6();

  clinical6.config.mobileApplicationKey = '123123123211';
  clinical6.device.technology = 'web';
  clinical6.device.udid = '192.0.0.1';
  clinical6.device.appVersion = '0.1';

  clinical6.config = {
    apiBaseUrl: 'https://dhsadobe.captivereach.com',
    track: { flows: false, gps: false }
  };

  clinical6.signIn(); // will automatically use {guest: true} and device
</script>

This is also to be used with ES6 or TypeScript supported technologies (ionic 2)

import { Component, ViewChild } from '@angular/core';
import { Platform, MenuController, Nav } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { HelloIonicPage } from '../pages/hello-ionic/hello-ionic';
import { ListPage } from '../pages/list/list';
import { AppVersion, Device } from 'ionic-native';
import { clinical6, Flow } from 'clinical6';


@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  // make HelloIonicPage the root (or first) page
  rootPage: any = HelloIonicPage;
  pages: Array<{title: string, component: any}>;

  constructor(
    public platform: Platform,
    public menu: MenuController
  ) {
    this.initializeApp();

    // set our app's pages
    this.pages = [
      { title: 'Hello Ionic', component: HelloIonicPage },
      { title: 'My First List', component: ListPage }
    ];
  }

  initializeApp() {
    this.platform.ready().then(() => {
      const f: Flow = new Flow();
      clinical6.config.mobileApplicationKey = '123123123211';
      clinical6.apiBaseUrl = 'https://ppdpassport.clinicalreach.com/';
      clinical6.device.udid = Device.uuid;
      clinical6.device.technology = Device.platform;

      AppVersion.getVersionNumber()
        .then(s => (clinical6.device.appVersion = s))
        .then(() => clinical6.signIn())
        .catch(reason => console.log(reason));


      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();
    });
  }

  openPage(page) {
    // close the menu when clicking a link from the menu
    this.menu.close();
    // navigate to the new page if it is not the current page
    this.nav.setRoot(page.component);
  }
}

Initialization

After loading Clinical6 in an HTML file, a new class of Clinical6 instance can be instantiated in JavaScript. You will need to pass in a Clinical6 instance url. If no url is passed, the default url to set will be localhost.

All services as well as a base Clinical6 class have instantiated objects that are camel case. In this example we use the clinical6 object.

import { clinical6 } from 'clinical6';

clinical6.apiBaseUrl = 'https://mysite.captivereach.com';

The clinical6 object has a device and config getter and setter to allow for various settings.

import { clinical6 } from 'clinical6';
clinical6.device.pushId = '28104321'; // default 'FAKE_ID'
clinical6.device.technology = 'ios'; // default null, must be 'android', 'ios', or 'web'
clinical6.device.udid = '2840-1afj03-afjsdf-238fj'; // default null
clinical6.device.appVersion = '0.0.1'; // default null

clinical6.config = {
  apiBaseUrl: 'https://mysite.captivereach.com',  // default undefined
  authToken: '2384af0j238fdjwe0', // default undefined
  track: {
    flows: true, // default true, this will automatically call postInsights on a flow 'go' and 'collect'
    gps: false // default false, this will automatically use gps when postInsights is called
  }
};

In addition, there are direct setters and getters for some of these options for config.

import { clinical6 } from 'clinical6';

clinical6.apiBaseUrl = 'https://mysite.captivereach.com';
clinical6.authToken = '2384af0j238fdjwe0';

Services

We have been focusing on cutting down the number of services that are used in the SDK. There are many dynamic services which we can access / make use of through a clinical6 object. With a clinical6 object we are able to perform the basic CRUD operations as well as get data for parent / child relationships.

Accessing Data / Get

With a clinical6 object we can get either all data or a single object back if there's a provided ID value. In order to get data we call the get() method on a clinical6 object and provide the class or an object with a type to retrieve data.

import { clinical6, Cohort } from 'clinical6';

// To get a list of Cohorts by importing a class 
import { clinical6, Cohort } from 'clinical6';
clinical6.get(Cohort).then(c => console.log(c));

// To get a list of Cohorts by importing providing an object 
import { clinical6 } from 'clinical6';
clinical6.get({ type: 'cohorts' }).then(c => console.log(c));

We can also get data back for a specific object, just include a valid ID.

import { clinical6, Cohort } from 'clinical6';

// To get a single cohort
clinical6.get({ id: 5, type: 'cohorts'});

In order to insert / update we have a couple of options. The first option is to use the save() on an object. If the object does not have an ID value, calling save() will insert the object. If an ID value is provided, save() will update the object.

import { clinical6, Cohort } from 'clinical6';

const myCohort = new Cohort();

// To insert you can use the .save() capability on an object that does not have an ID
myCohort.save(); // insert the newly created Cohort object

// With an ID value, save() will now make a PATCH request and will update the object
myCohort.id = 5;
myCohort.save(); // updating the Cohort object

Additionally, we can use a clinical6 object to either insert or update.

import { clinical6, Cohort } from 'clinical6';

// Using clinical6 to insert
clinical6.insert(new Cohort({...}));

// Using clinical6 to update an object
const myCohort = new Cohort();
myCohort.id = 5;
clinical6.update(myCohort);

Deleting objects is very similar to inserting / updating. You can use either the delete() method on an object directly or you can use a clinical6 object and pass in the object that you'd like to delete into the delete() method.

import { clinical6, Cohort } from 'clinical6';

// Using an object directly to delete
myCohort.delete();

// Using clinical6 delete() method on an object to delete
const myCohort = new Cohort();
myCohort.id = 5;

clinical6.delete(myCohort);

Lastly, we are able to get parent / child relationship data back by using a clinical6 object and calling the getChildren method.

CORS

When using the SDK in a Cordova app, CORS is not an issue because the app essentially runs on a file:/// URI. The app controls access through domain whitelisting.

However, when developing against this SDK not in an app, CORS errors often prevents the SDK from working. To bypass CORS errors, do one of the following:

  1. Update the Clinical6 endpoint to allow your endpoint access (Best solution, may not always be possible)
  2. Access the Clinical6 endpoint through a proxy that injects CORS headers (2nd best solution, always possible)
  3. Disable CORS in Chrome (Quickest solution, but NOT recommended as long term development plan. Opens up browser to many vulnerabilities)

Top

NPM Scripts

This repository contains several helpful npm requests that ensures good code quality, runs tests, compiles ECMA6 code to ECMA5, and generates JSDOC documentation from the source code.

The following scripts are available to use for this respository just by navigating to the local installment of this repository and typing in the following in the command-line.

Script Description
npm run build Runs task sequence clean, compile, webpack, lint, and then test
npm run compile Converts the ECMA6 js files in src and test folders code and puts them in src.babel and test.babel directories
npm run clean Deletes generates js files in test.babel and src.babel folders.
npm run doc Compiles all the comments in the source code and creates html files that define all Classes, methods, parameters, and description in a user-friendly format.
npm install Runs task sequence clean, compile, webpack, lint, and then test
npm run lint Checks the source code for code style consistency using ESLINT configurations.
npm test Runs all the unit tests in the test.babel folder
npm run webpack Combines the src.babel js files into clinical6.js that can run on the browser or node environments each class available.

Requirements

Before you start coding, you'll need to set up your development environment:

Software Version Instructions Purpose
NodeJS 5.5.0 Go to nodejs.org, download Node, and install with default settings using your machine's default installer JavaScript engine
NPM 3.3.12 Node Package Manager (NPM) is included in the default installation of Node Package manager
Any JS IDE -- Choose an IDE that supports JavaScript coding (e.g. Webstorm v11.0.3+ or Sublime Text 3) JavaScript IDE
Git ^2.5.0 Download, install, and verify "git" is an executable command from your terminal Version Control

Top