Skip to content

Instantly share code, notes, and snippets.

@lbrenman
Last active June 11, 2018 11:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lbrenman/4a900bf40fd72de624c1a99fb07e8e9a to your computer and use it in GitHub Desktop.
Save lbrenman/4a900bf40fd72de624c1a99fb07e8e9a to your computer and use it in GitHub Desktop.
Arrow Builder coding notes, tips and tricks

Arrow Builder coding notes, tips and tricks

  • Create a new project using:

    appc new
  • For npm's required in your project, you need to do the following:

    • "sudo npm install " for running locally OR add to package.json -> devDependencies section

    • add to package.json -> dependencies section, e.g.

      ...
      "acs-node": "^0.9.5"
      ...
  • Prior to publishing, change container size and number of containers in appc.json -> cloud section:

    ...
    "container": "Medium",
    "minimum": 2,
    "maximum": 2,
    ...
  • Publish using

    appc publish
  • Re-publishing. After making changes, use the --force

    appc publish --force
  • By default you will not be able to access the developers console without editing /conf/default.js as follows:

    ...
    enableAdminInProduction: true,
    ...
  • Check status of your publishing or re-publishing using:

    appc cloud list <app name>
  • Check server console logging:

    appc cloud logcat <app name>
  • Check the build log:

    appc cloud loglist --build_log  <app name>
  • Check the performance metrics (cpu/mem):

    appc cloud usage <app name>
  • To remove ArrowDB Prod/Dev data hassles:

    • Save, then remove appc.arrowdb.development.js from /conf folder
    • Save, then rename appc.arrowdb.production.js to appc.arrowdb.js in /conf folder
    • Now Arrow in dev or production will access same ArrowDB so you won't have to deal with populating data in two environments
  • Code snipets useful in blocks:

    • Check REST verb:

      ...
      action: function (req, resp, next) {
        ...
      	if(req.method==="GET") {
      		var body = JSON.parse(resp.body);
      		var data = body[body.key];
      		var dataLen = data.length;
          ...
        }
        ...
      }
    • Get header:

      var deviceid = req.get('deviceid'); //get value of header deviceid
    • Get query parameter:

      var whereClause = JSON.parse(req.params.where); //get query parameter and convert to object
      if(whereClause.hasOwnProperty('userid')) {...} // check for existence of field
    • Reply to API request and block next step(s):

      resp.response.status(500);
      resp.send({"success": false,"error":"unsupported API"});
      next(false);
  • Add blocks to models for specific API call types:

      ...
      "actions": [
    		"create",
    		"read",
    		"delete"
    	],
    	"beforeCreate": "validatewatchlistcreate",
    	"beforeFindAll": "unsupportedAPI",
    	"beforeQuery": "validatewatchlistquery",
    	"afterQuery": "addstockquote_",
    	"afterFindOne": "addstockquote_",
      ...
    	"singular": "WatchList",
    	"plural": "WatchLists"
    });
    • before$METHOD$ - One or more blocks to be executed before the request to a particular method. This could be “beforeQuery”, “beforeDelete”, etc. See “before” above for more information.

    • after$METHOD$ - One or more blocks to be executed after the request to a particular method. This could be “afterQuery”, “afterDelete”, etc. See “after” above for more information.

  • Add multiple blocks:

    ...
    before: ['balanceQueryUseridCheck', 'balanceHeaderDeviceidCheck'],
    ...
    connector: 'appc.arrowdb',
    actions: [
    ...
  • Multiple similar back end connections. See blog post

    • Modify connector config file:

        module.exports = {
          connectors: {
              'appc.mysql1': {
                  connector: 'appc.mysql',
                  connectionPooling: true,
                  connectionLimit: 10,
      
              database: 'salesreport',
              user: 'root',
              password: 'XXXX',
              host: 'localhost',
              port: 3306,
      
              // Create models based on your schema that can be used in your API.
              generateModelsFromSchema: true,
      
              // Whether or not to generate APIs based on the methods in generated models.
              modelAutogen: true
      
          },
          'appc.mysql2': {
              connector: 'appc.mysql',
              connectionPooling: true,
              connectionLimit: 10,
      
              database: 'lbmysql',
              user: 'lbrenman',
              password: 'XXXX',
              host: 'db4free.net',
              port: 3306,
      
              // Create models based on your schema that can be used in your API.
              generateModelsFromSchema: true,
      
              // Whether or not to generate APIs based on the methods in generated models.
              modelAutogen: true
      
          }
      }
      
      };
    • Access in model:

      var Arrow = require("arrow");
      
      var Model = Arrow.createModel("combined",{
          "fields": {
              "row": {
                  "model": "appc.mysql1/region",
                  "type": "Object"
              },
              "us": {
                  "model": "appc.mysql2/region",
                  "type": "Object"
              }
          },
          "connector": "appc.composite",
          "actions": [
              "create",
              "read",
              "update",
              "delete",
              "deleteAll"
          ],
          "singular": "combined",
          "plural": "combineds"
      });
      
      module.exports = Model;
  • Programmatically access models

    • FindAll

      device.findAll(function(err, data) {
      	if(err) {
      		console.log('utils: device findAll error = '+JSON.stringify(err));
      	} else {
      		checkEachDevice(data);
      	}
      });
    • Query

      var user = Arrow.getModel("user");
      user.query({username: userid}, function(err, data){
        if(err) {
          sendError(req, resp, next, "error accessing user database");
        } else {
          console.log('user found, user = '+JSON.stringify(data));
          // get approved device list and compare with deviceid
          var approvedDevices = data[0].devices;
          ...
        }
        ...
      });
    • Query with update of record

      device.query({deviceId: deviceId}, function(err, data) {
      	if(err) {
      		console.log('utils: device query error = '+JSON.stringify(err));
      		if(callback) {callback({success:false, msg:"error accessing device database"});}
      	} else {
      		var device = data[0];
      		console.log('utils: device = '+JSON.stringify(device));
      
      		// Update the lastUpdateDate timestamp to now and clear the missedDoseAlerted flag
      		// so that missed dose can be triggered if a dose is missed
      		var date = new Date();
      		data[0].lastUpdateDate=date;
      		data[0].missedDoseAlerted=false;
      
      		// decrement remaining doses
      		data[0].doseRemaining -= 1;
      
      		data[0].update();
      		if(callback) {callback({success:true});}
      	}
      });
    • FindByID

      deviceLog.findByID(item.id, function(err,d){
      		d.delete(function(err,result){
      				if(err) {
      					console.log('utils: deviceLog delete err = '+err);
      				} else {
      					console.log('utils: deviceLog delete success');
      				}
      		});
      		d.update();
      	});
    • Create

      model.create({to: mobile, body: msg}, function(err, instance){
      	if(err) {
      			console.log('utils: Twilio message create error, err'+JSON.stringify(err));
      		} else {
      			console.log('utils: Twilio message sent');
      		}
      });
@alasdairhurst
Copy link

@lbrenman

You shouldn't have to run sudo when doing npm install in a local project (it will mess up permissions). A quick way of saving a module to your project is doing
npm install module --save
this will add it to your package.json
--save-dev
will add it to dev dependencies
To get a specific version

npm install module@version

Maybe also mention about bumping the version before publishing. --force is not really meant to be the standard method of publishing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment