Qlik Community

Qlik Design Blog

All about product and Qlik solutions: scripting, data modeling, visual design, extensions, best practices, etc.

Employee
Employee

enigma.js with React Hooks API and React Context

enigma-react.png

 

For our projects on the Qlik Demo Team, we’re now using React Hooks with functional components in place of class components. I’ve been playing around with ways to connect to a doc with enigma.js and use it in React components and this is what I’ve come up with most recently. Check out the code and notes below, or download the files and try it out yourself, and let me know what you think, if you like it or if you’re doing anything similar or if you have any ideas on improving it.

 

src/qDoc.config.js

This file imports enigma.js and defines the config for connecting to a Qlik doc, and exports an openDoc function which returns a promise which will resolve to the doc.

 

const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.20.0.json');
const SenseUtilities = require('enigma.js/sense-utilities');

const config = {
  host: 'sense-demo.qlik.com',
  secure: true,
  port: 443,
  prefix: '',
  appId: '372cbc85-f7fb-4db6-a620-9a5367845dce',
};

const url = SenseUtilities.buildUrl(config);
const session = enigma.create({ schema, url, suspendOnClose: true });

// open doc and return promise which will resolve to doc
export const openDoc = () => (
  session.open().then((global) => global.openDoc(config.appId))
);

// close session
export const closeSession = () => (
  session.close()
);

 

 

src/components/QDoc.jsx

This file creates and exports a React context and creates and exports a QDocProvider component. The QDocProvider component is responsible for connecting to the doc by calling the openDoc function from src/qDoc.config.js and storing the doc in state. Once the doc is available it renders the context provider and children.

 

import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { openDoc, closeSession } from '../qDoc.config';

export const QDocContext = React.createContext();

const QDocProvider = ({ children }) => {
  const [qDoc, setQDoc] = useState(null);
  useEffect(() => {
    (async () => {
      setQDoc(await openDoc());
    })();
    return closeSession;
  }, []);
  return (
    <>
      {!qDoc && <div>Connecting to Qlik...</div>}
      {qDoc && (
        <QDocContext.Provider value={qDoc}>
          {children}
        </QDocContext.Provider>
      )}
    </>
  );
};

QDocProvider.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]),
};
QDocProvider.defaultProps = {
  children: null,
};

export { QDocProvider };

 

 

src/components/App.jsx

This component is the entry point component and just wraps a component called SomeConsumer in the QDocProvider component imported from src/components/QDoc.jsx.

 

import React from 'react';
import { QDocProvider } from './QDoc';
import SomeConsumer from './SomeConsumer';

const App = () => (
  <>
    <QDocProvider>
      <SomeConsumer />
    </QDocProvider>
  </>
);

App.propTypes = {};

export default App;

 

 

src/components/SomeConsumer.jsx

This component consumes the QDoc context and can use the Qlik doc.

 

import React, { useContext } from 'react';
import { QDocContext } from './QDoc';

const SomeConsumer = () => {
  const qDoc = useContext(QDocContext);
  console.log(qDoc); // print qDoc to console to make sure everything is working
  return (
    <>

    </>
  );
};

export default SomeConsumer;

 

 

Project is attached. Download it, play around, sound off.