How to...
Overview
The Glue42 React Hooks package is a library providing custom React hooks for the Glue42 Javascript libraries - @glue42/web and @glue42/web-platform, if you are working on a Glue42 Core project, or @glue42/desktop, if you are working on a Glue42 Enterprise project. The examples below use the Glue42 Enterprise JavaScript library. The Glue42 React Hooks library allows you to start using Glue42 features in your React apps idiomatically in the context of the React framework.
Prerequisites
The Glue42 React Hooks library comes with the latest version of the Glue42 Enterprise JavaScript library, but requires the React and ReactDOM libraries installed. To install the packages, navigate to the root directory of your project and run:
npm install --save @glue42/react-hooks react react-dom
Library Features
The Glue42 React Hooks library offers a way to consume the APIs of the Glue42 Enterprise JavaScript library in your web apps via React Hooks and React Context. The Glue42 React Hooks library provides the following features described below.
Context
The <GlueProvider />
is a React context provider component. It invokes a factory function (with default or user-defined configuration) which initializes the Glue42 Web library. The glue
object returned by the factory function is set as the context value.
Below is the signature of the <GlueProvider />
component:
interface GlueInitSettings {
web?: {
config?: Glue42Web.Config;
factory?: Glue42WebFactoryFunction;
};
webPlatform?: {
config?: Glue42WebPlatform.Config;
factory?: Glue42WebPlatformFactoryFunction;
};
desktop?: {
config?: Glue42.Config;
factory?: Glue42DesktopFactory;
};
}
interface GlueProviderProps {
children: ReactNode;
settings: GlueInitSettings;
fallback?: NonNullable<ReactNode> | null;
}
GlueProvider: FC<GlueProviderProps>;
The table below describes the properties of the GlueInitSettings
object.
Property | Description |
---|---|
web |
Optional. An object with two properties: config and factory . The config property accepts a configuration object for the Glue42 Web library. The factory property accepts the factory function exposed by Glue42 Web. You should define this object if your app is a Web Client. |
webPlatform |
Optional. An object with two properties: config and factory . The config property accepts a configuration object for the Web Platform library. The factory property accepts the factory function exposed by Glue42 Web Platform. You should define this object if your app is a Web Platform app (or Main app) in the context of Glue42 Core. |
desktop |
Optional. An object with two properties: config and factory . The config property accepts a configuration object for the @glue42/desktop library used in Glue42 Enterprise. The factory property accepts the factory function exposed by the library. You should define this object if your app is a Glue42 Enterprise app. |
Note that you can define either the web
, or the webPlatform
property together with desktop
. This is useful if you want your app to have different initialization characteristics in Glue42 Core and Glue42 Enterprise.
All properties are optional, but it is recommended that you provide the factory functions explicitly. If no factory functions are provided, the library will try to select an appropriate function attached to the global window
object.
The table below describes the properties of the GlueProviderProps
object.
Property | Description |
---|---|
children |
Required. React components which may contain Glue42 related logic. |
settings |
Required. A settings object containing the desired factory functions and configuration objects. |
fallback |
Optional. A React component to display while initializing Glue42. |
GlueContext
is the React context which is used by the <GlueProvider />
component. You can consume this context from anywhere inside you app with the default React hook useContext()
.
GlueContext: Context<Glue42Web.API | Glue42.Glue>;
Hooks
The useGlue()
hook is a React hook which will invoke the callback that you pass to it.
Below is the signature of useGlue()
:
<T = undefined>(
cb: (glue: Glue42Web.API | Glue42.Glue, ...dependencies: any[]) => void | T | Promise<T>,
dependencies?: any[]
) => T;
Parameter | Description |
---|---|
cb |
Required. Async or sync callback function that will be invoked with the glue object and an array of user-defined dependencies . The callback may or may not include Glue42 related code. |
dependencies |
Optional. An array of user-defined variables that will trigger the invocation of the provided callback based on whether the value of any of the specified variables has changed (same functionality as the useEffect() React hook). |
The useGlueInit()
hook is a React hook which initializes the provided Glue42 JavaScript library. It accepts a required settings object, identical to the GlueInitSettings
object.
UseGlueInitFunc = (
settings: GlueInitSettings
) => Glue42Web.API | Glue42.Glue;
useGlueInit: UseGlueInitFunc;
Usage
Below you can see some examples of using the Glue42 React Hooks library.
Initialization
To access the Glue42 Enterprise APIs, initialize and (optionally) configure the Glue42 Enterprise JavaScript library. You can do this in two ways - by using the <GlueProvider />
component or the useGlueInit()
hook. The difference is that the <GlueProvider />
initializes the Glue42 Enterprise library and makes the returned API object (glue
) globally available by automatically assigning it as a value to GlueContext
, while the useGlueInit()
hook initializes the library and returns an API object (glue
) which you then have to make available to your other components by passing it as a prop, by creating a context or by attaching it to the global window
object.
Add the <GlueProvider />
component by wrapping your other components inside it (preferably the root one). Pass the settings object to the <GlueProvider />
. It will initialize the Glue42 Enterprise JavaScript library and make the Glue42 Enterprise APIs available in your app by setting the returned glue
object as the value of GlueContext
:
//index.js
import Glue from "@glue42/desktop";
import { GlueProvider } from "@glue42/react-hooks";
ReactDOM.render(
// Wrap your root component in the `<GlueProvider />` in order
// to be able to access the Glue42 Enterprise APIs from all child components.
<GlueProvider fallback={<h2>Loading...</h2>} settings={{ desktop: { factory: Glue } }}>
<App />
</GlueProvider>,
document.getElementById("root")
);
You can also initialize the Glue42 Enterprise JavaScript library with the useGlueInit()
hook. Below is an example of conditional rendering of a component based on whether the Glue42 Enterprise API is available or not.
import Glue from "@glue42/desktop";
import { useGlueInit } from "@glue42/react-hooks";
const App = () => {
// Example custom configuration for the Glue42 Enterprise library.
const settings = {
desktop: {
config: { appManager: "full" },
factory: Glue
}
};
const glue = useGlueInit(settings);
return glue ? <Main glue={glue} /> : <Loader />;
};
export default App;
Remember that when you initialize the Glue42 Enterprise library with the useGlueInit()
hook, you must provide the glue
object to your nested components to be able the use the Glue42 Enterprise APIs in them. For example, use React Context or attach it to the global window
variable.
Consuming Glue42 APIs
After the Glue42 Enterprise JavaScript library has been successfully initialized, you can access the Glue42 Enterprise APIs with the built-in React hook useContext()
passing GlueContext
as its argument, or with the useGlue()
hook.
Note that this library is just a thin wrapper designed to work with both @glue42/web
and @glue42/desktop
. For that reason, if you are using React with TypeScript, you should type cast the initialized glue
object to the appropriate type, because the default type is Glue42Web.API | Glue42.Glue
.
Below is an example of accessing the glue
object with GlueContext
and using the Shared Contexts API to get the context of the current window:
import { useContext, useState, useEffect } from "react";
import { GlueContext } from "@glue42/react-hooks";
const App = () => {
const [context, setContext] = useState({});
// Access the Glue42 Enterprise APIs by using the `glue` object
// assigned as a value to `GlueContext` by the `<GlueProvider />` component.
const glue = useContext(GlueContext);
useEffect(() => {
setContext(glue.windows.my().context);
}, []);
return (
<div>
<h2>My Window Context</h2>
<pre>{JSON.stringify(context, null, 4)}</pre>
</div>
);
};
export default App;
Below is an example of accessing the glue
object with the useGlue()
hook and using the Window Management API to open an app in a new window on button click:
import { useGlue } from "@glue42/react-hooks";
const App = () => {
const openWindow = useGlue(glue => (name, url) => {
glue.windows.open(name, url);
});
return (
<table>
<tr>
<td>Client List</td>
<td>
<button
onClick={() => {
openWindow("ClientList", "http://localhost:8080/client-list");
}}
>
Start
</button>
</td>
</tr>
</table>
);
};
export default App;
This is an example of using the Interop API to get the window title through an already registered Interop method:
import { useGlue } from "@glue42/react-hooks";
import { useState } from "react";
const App = () => {
const [title, setTitle] = useState("");
const getTitle = useGlue(glue => methodName => {
glue.interop.invoke(methodName).then(r => setTitle(r.returned._result));
});
return (
<>
<h2>{title}</h2>
<button
onClick={() => {
getTitle("T42.Demo.GetTitle");
}}
>
Get Title
</button>
</>
);
};
export default App;
Testing
You can use your own factory function for initializing the Glue42 Enterprise JavaScript library. This is useful in Jest/Enzyme tests when you want to mock the Glue42 library:
//index.js
import { mount } from "enzyme";
import { GlueProvider } from "glue42/react-hooks";
// Define a factory function which will mock the Glue42 Enterprise library.
const glueFactory = () => {
const glueObject = {
interop: { invoke: jest.fn(), register: jest.fn() },
contexts: { subscribe: jest.fn(), update: jest.fn() },
windows: { open: jest.fn(), my: jest.fn() }
};
return Promise.resolve(glueObject);
};
describe("Mock Glue42", () => {
it("Should mock the Glue42 library.", () => {
const wrapper = mount(
// Pass your factory function to the `<GlueProvider />` component.
<GlueProvider settings={{ desktop: { factory: glueFactory} }}>
<App />
</GlueProvider>
);
// Your logic here.
});
});
For additional information on testing React hooks, see @testing-library/react-hooks.
Glue42 JavaScript Concepts
Once the Glue42 React library has been initialized, your app has access to all Glue42 functionalities. For more detailed information on the different Glue42 concepts and APIs, see:
Reference
For a complete list of the available JavaScript APIs, see the Glue42 JavaScript Reference Documentation.