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.

Reading the comments here, it seems as we'll be short on time to show & discuss everything during the CUG meeting! wink

I'm looking forward to see these nice add-ons & howto's.

See you all at the symposium!

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

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.