Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
danelooman
Creator
Creator

Access the Enigma API in a Mashup BEFORE opening an App

I am trying to get access to the enigma API before opening an app. I have seen the way where you open the app with the capability api then explore and find the enigma model for both the app and the global. That will not work for my needs. I am trying to open an app with no data and the capability version is bugged (ticket pending) to always be set to open with data. This means by the time Engima gets to it the app has been opened with data and can't be reopened. If anyone has an example or an idea it would be greatly appreciated.  

Labels (1)
  • API

1 Solution

Accepted Solutions
alex_colombo
Employee
Employee

Hi @danelooman , as mentioned above, you shouldn't need to use Capability APIs based on your requirement. Anyway, please see below example, it works even if you remove all require.js stuff.

I opened first an enigma session and then run require and all its stuff for using Capability APIs. Remember to inject first enigma.min.js and then require in html code like below

 

<script src="https://unpkg.com/enigma.js@2.7.0/enigma.min.js"></script>
<script src="../../resources/assets/external/requirejs/require.js"></script>

 

 

Below js code, this will open two websockets, one by enigma.js and one by require.js (Capability APIs). Authentication is not managed on enigma.js side in this example. It will work only if you open another tab of your browser with Qlik already authenticated.

 

//enigma.js stuff
(async () => {
  // open app
  const schema = await (await fetch('https://unpkg.com/enigma.js/schemas/3.2.json')).json();
  const appId = 'cd5a3779-1d36-45c8-a343-12552755914c';
  const url = `wss://_qlik_server_/app/${appId}`;
  const session = window.enigma.create({ schema, url });
  const app = await (await session.open()).openDoc(appId);
  console.log('enigma doc', app)

})();

//require.js Capability APIs
var prefix = window.location.pathname.substr( 0, window.location.pathname.toLowerCase().lastIndexOf( "/extensions" ) + 1 );

var config = {
	host: window.location.hostname,
	prefix: prefix,
	port: window.location.port,
	isSecure: window.location.protocol === "https:"
};
//to avoid errors in workbench: you can remove this when you have added an app
var app;
require.config( {
	baseUrl: (config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port : "" ) + config.prefix + "resources"
} );



require( ["js/qlik"], function ( qlik ) {

	var control = false;
	qlik.on( "error", function ( error ) {
		$( '#popupText' ).append( error.message + "<br>" );
		if ( !control ) {
			control = true;
			$( '#popup' ).delay( 1000 ).fadeIn( 1000 ).delay( 11000 ).fadeOut( 1000 );
		}
	} );

.....
});

 

 

View solution in original post

8 Replies
Aiham_Azmeh
Employee
Employee

Hi,

I hope I understand well your intention... have you tried to use session apps instead (or more exactly if you need the objects from the app session app from app)

more doc: https://qlik.dev/apis/json-rpc/qix#session-apps

 

alex_colombo
Employee
Employee

Hi @danelooman, openApp method with openWithoutData set to true is looks like bugged, our R&D is investigating on it. 
Could you please describe better your requirement? Why do you need to first open the app without data and then open with data?
An idea could be to first use enigma.js for establish a connection with Qlik app before you load your capability API. with enigma.js and Engine API you can open an app without data.

danelooman
Creator
Creator
Author

@alex_colombo and @Aiham_Azmeh . Thanks for the replies, let me explain our goal. We have a lot of users who store versions of large apps in their workspace. (Think v1, v2, v3 of the same app all clogging up our storage) We have built a mashup that shows them a list of their workspace apps with a button that would open the app with noData and then save it. We have told our developers to just use the qmc but management has requested a simpler approach. Alex do you have an example of what you suggest? We have tried but with the mashup it seems to be difficult. 

alex_colombo
Employee
Employee

@danelooman  the goal here basically is to reduce the app space with a single click from a mashup opening the app without data and the save it, is that correct?
If so, you can take a look at enigma.js documentation where you can find examples on how to use it. I guess you don't need to use Capability APIs, becuase you just need to open the doc and then save it with no data

danelooman
Creator
Creator
Author

@alex_colombo thank you, that is basically what we are looking for, a template for how to connect to enigma in a mashup. I see at the last section of the documentation there is a way to connect through the fetch API. I will give that a shot and report back. I appreciate you helping us with this work around. 

danelooman
Creator
Creator
Author

@alex_colombo  No dice, I am getting WSS failed errors. Below is the code I imported straight from the enigma docs. I changed my server to MyQlikSenseServer just for privacy's sake. I also added  <script src="https://unpkg.com/enigma.js/enigma.min.js"></script> above the call for this JS and the requireJS in my document head. If I add the port 9076 to it then it just spins and never connects. I believe I need to add the user and directory to the WS which I can get from qlik.global but I was hoping to use the session id cookie that is generated when they log in to the mashup.

 

var prefix = window.location.pathname.substr( 0, window.location.pathname.toLowerCase().lastIndexOf( "/extensions" ) + 1 );
var config = {
	host: window.location.hostname,
	prefix: prefix,
	port: window.location.port,
	isSecure: window.location.protocol === "https:"
};
require.config( {
	baseUrl: ( config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port : "") + config.prefix + "resources"
} );

require( ["js/qlik"], function ( qlik ) {
	
	fetch('https://unpkg.com/enigma.js/schemas/12.34.11.json')
    .then(response => response.json())
    .then(schema => {
      const session = enigma.create({
        schema,
        url: `wss://MyQlikSenseServer.com/app/engineData`,
        createSocket: url => new WebSocket(url)
      })

      session.open()
        .then(global => global.engineVersion())
        .then(result => document.body.innerHTML = result.qComponentVersion)
        .then(() => session.close())
    });
	
} );

 

 

 

 

alex_colombo
Employee
Employee

Hi @danelooman , as mentioned above, you shouldn't need to use Capability APIs based on your requirement. Anyway, please see below example, it works even if you remove all require.js stuff.

I opened first an enigma session and then run require and all its stuff for using Capability APIs. Remember to inject first enigma.min.js and then require in html code like below

 

<script src="https://unpkg.com/enigma.js@2.7.0/enigma.min.js"></script>
<script src="../../resources/assets/external/requirejs/require.js"></script>

 

 

Below js code, this will open two websockets, one by enigma.js and one by require.js (Capability APIs). Authentication is not managed on enigma.js side in this example. It will work only if you open another tab of your browser with Qlik already authenticated.

 

//enigma.js stuff
(async () => {
  // open app
  const schema = await (await fetch('https://unpkg.com/enigma.js/schemas/3.2.json')).json();
  const appId = 'cd5a3779-1d36-45c8-a343-12552755914c';
  const url = `wss://_qlik_server_/app/${appId}`;
  const session = window.enigma.create({ schema, url });
  const app = await (await session.open()).openDoc(appId);
  console.log('enigma doc', app)

})();

//require.js Capability APIs
var prefix = window.location.pathname.substr( 0, window.location.pathname.toLowerCase().lastIndexOf( "/extensions" ) + 1 );

var config = {
	host: window.location.hostname,
	prefix: prefix,
	port: window.location.port,
	isSecure: window.location.protocol === "https:"
};
//to avoid errors in workbench: you can remove this when you have added an app
var app;
require.config( {
	baseUrl: (config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port : "" ) + config.prefix + "resources"
} );



require( ["js/qlik"], function ( qlik ) {

	var control = false;
	qlik.on( "error", function ( error ) {
		$( '#popupText' ).append( error.message + "<br>" );
		if ( !control ) {
			control = true;
			$( '#popup' ).delay( 1000 ).fadeIn( 1000 ).delay( 11000 ).fadeOut( 1000 );
		}
	} );

.....
});

 

 

danelooman
Creator
Creator
Author

@alex_colombo Thank you so much. I can't tell you how much this has helped us. We got it working and its going to really let us flex the power of qlik sense in our business.