Nice tip! Btw, if you want a real signed certificate, you can also use Let's Encrypt certificates with an auto-renew client for all types of operating systems (because these free certificates expire after 4 months). You can also use this trick for all kinds of servers requiring ssl encryption when facing the public internet.

A quick idea: doing a search for TWAIN on the NPM repository for JavaScript & Node.js, it seems you can quite easily add the ability to scan images to any web application:

  • add the Scanner.js module to your web page
  • add the scanner.scan() method in your webpage to show a native TWAIN dialog in the user's browser
  • from the examples in their developers guide, you can then show the images in the browser & upload them to the server (this should work with any back-end which allows file uploading)
  • I would upload the images to a (protected) image directory on your webserver instead of storing them as a blob inside the CACHE.DAT - your database will grow very quickly and it becomes much more difficult to show images e.g. in a browser page

You can easily search for more TWAIN npm modules on npm - Scanner.js seems to be the most popular one these days. You don't have to re-invent the wheel, npm contains a gazillion of modules for nearly every application you can think of!

Excellent work Rob, thank you for the hard integration work!

I got my IRIS container running on AWS in ... less than 15 mins (I used a free tier t2.micro instance). Of which 2/3 of the time was learning to know the AWS website! wink

Let's start developing now the latest React/Vue.js/... apps with QEWD.js/Node.js back-end running on IRIS ... which is very easy now because the complete back-end is in a Docker container to try out.

And you have the choice at the front-end: communicating with the back-end using WebSockets or REST endpoints using e.g. the react-qewd or vue-qewd module ... all abstracted for you using very easy methods like this.$qewd.send() (Vue.js with WebSockets) or axios.post() (using REST calls).

To iterate over just the global nodes you need, see my other comment below. You need an index global to do this.

Please note that QEWD.js and the Node.js adapter are very different: the Node.js client is a low-level adapter to access the Caché/IRIS database, while QEWD.js is a full multi-process back-end application server (in the underlying code, QEWD is using the ewd-document-store abstraction and, in turn, uses the IRIS node.js client to access Caché/IRIS). In fact, it removes you from writing a lot of system "plumbing" code to get your front-end code working with Caché/IRIS. You'll find QEWD examples for use with React apps at react-qewd and with Vue.js/Nuxt.js apps at vue-qewd.

@Fabian Pie one thing I forgot: you should also build an index from the Customer global, e.g. based on Robert's code snippet:

set id="" for {
  set id=$order(^Customer(id)) quit:id=""
  set city=$get(^Customer(id,"Address",1))
  set name=$get(^Customer(id,"Name"))
  if $length(city)&$length(name) set ^CustomerIndex(city,name,id)=""
}

Now you can easily filter on the selected city and loop over the (sorted) customer names by iterating over the ^CustomerIndex global using similar JavaScript code as above. By using globals, you get sorting for free! And you don't need to traverse the whole customer global anymore.

You should have a look at the ewd-document-store npm module, this module contains high-level global access methods for Node.js. Btw, it's the underlying module used also by the QEWD.js back-end server for Node.js & Caché/IRIS.

E.g. you can iterate easily over your Customer global using:

var DocumentStore = require('ewd-document-store');

// put the appropriate irisXXX.node version inside node_modules
// and rename it to iris.node
var iface = require('iris');
var db = new iface.IRIS();

// Change these parameters to match your IRIS system:
var ok = db.open({
  path: '/opt/iris/mgr',
  username: '_SYSTEM',
  password: 'SYS',
  namespace: 'USER'
});

// bind the iris.node db instance to the high-level DocumentStore
var documentStore = new DocumentStore(db);
// instantiate a DocumentNode object to access the Customer global
var customerNode = new documentStore.DocumentNode(‘Customer’);
// iterate over customerId's using the forEachChild() method
customerNode.forEachChild(function (customerId) {
  console.log(customerId); // will output 1, 2, 3, ...
  // access sub-nodes using the $() method using method chaining
  // and retrieve the city using the value property
  if (customerNode.$(customerId).$('Address').$('1').value == 'London') {
    // do what's needed with a London customer ...
  }
});

// probably, customerNode.forEachLeafNode() is even more appropriate

// close the db connection to IRIS
db.close();

I haven't completely tested the code above, but you should get the idea. The module provides you with some cool high-level NoSQL access methods to iterate over a global  in JavaScript. The methods of DocumentStore and DocumentNode allow you to access very large globals without size and/or memory limitations (see documentation).

Yes, this makes no difference at software level and should work exactly the same with RS422/485 as with RS232.

The difference is that with RS232 the hardware cable uses single-ended signals, with RS422/485 the cable uses differential signals. In addition, RS485 can transport signals over much longer cables and can talk to multiple devices connected to the same cable, in that case a protocol with device uid's is needed.

So Caché can talk in an identical way to a RS485 device, but the (software) protocol will probably be different.

You'll need also a hardware device (converter/bus driver) to convert the RS232 signals from your pc/server to RS485 differential signals.

Btw, as the error occurs in the require() already, I still suspect there is a Node.js module version mismatch:

https://npm.community/t/node-module-version-confusion/2982

https://github.com/kelektiv/node.bcrypt.js/issues/635

You need to double check which Node.js version and iris.node version you have. I suspect there is a mismatching iris.node version somewhere on your machine that require() finds in the module search path.

This is a basic test script I'm using to test basic connectivity from Node.js v8.x, the iris.node module version included is meant for an IRIS x64 instance on Windows with Node.js v8.x x64 installed.

It contains everything you need, you can immediately run it - you should see the same results. The test script assumes IRIS is installed in C:\InterSystems\IRIS and the _SYSTEM user contains the default password. If not, you need to change this in the example script iristest.js in the db.open() parameters.

iris_node_connector_test.zip

IRIS Node.js connector test script

Btw, if you're developing a React Native app and you need a back-end server for IRIS, you can try the react-qewd module for Node.js for use with the QEWD.js back-end server for IRIS.

A few more things to check: 

  • when you installed Node.js version 10.x, you need iris1000.node (for version 8.x, you need iris800.node)
  • you can ask for the most recent build via WRC
  • the IRIS architecture version (x86 or x64) must match the iris.node architecture version

If the module still refuses tot load, I'll upload an example test.js file I use myself to test basic functionality.

The instructions in the docs are different from the usual place a node.js module like iris.node should be put.

Usually, you create a test.js file in a directory of your choice, e.g. in C:\Test and inside this directory, you create a C:\Test\node_modules directory where iris.node should be placed.

When you do:

var iris = require('iris')

Your test.js file will look for it inside node_modules.

Hi Scott,

I assume you discovered a useful Node.js module for image manipulation in the NPM registry.

As Bernd Mueller describes in an article about callouts, I think the most efficient way is to host your Node.js module in an Node.js/Express server endpoint and make a REST call from within ObjectScript to do this. As Bernd describes, you can do this quite easily using this technique because REST calls are much more efficient than starting external (Node.js) process instances with $ZF() for each callout.

However, there's also a much more powerful variant of Node.js/Express server where you have access in JavaScript to your Caché/IRIS data too using the latest QEWD-Up server. To just manipulate an image externally this will probably look as an overkill, but for other external JavaScript modules where you need to have access to your data too, this multiprocess Node.js/Express server is a perfect fit for applications needing external functionality.

I'm using this for my applications too to use external JavaScript modules, giving you access to pretty much everything you can imagine and the NPM registry has an out-of-the-box module available for.

HTH,

Ward