Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content
Announcements
March 26 at 10am ET: See how Qlik drives growth and value in ISV segment - REGISTER NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
nilshapavan
Employee
Employee

REST API call for making sheet public in Qlik Analytics App

I was looking for REST API call for making sheet public in Qlik Analytics App. I was not able to find from API doc - https://qlik.dev/apis/rest/. I also checked in the network call but couldn't find it. 

 

Labels (2)
1 Solution

Accepted Solutions
dxa
Employee
Employee

Hi! I think that the problem is that "global.openDoc" takes more parameters than just the ID of the app.

 

(async () => {
    const enigma = require("enigma.js");
    const schema = require("enigma.js/schemas/12.612.0");
    const WebSocket = require("ws");
  
    // replace with your information
    const appId = "<app-id>";
    const tenant = "<your-tenant.qlikcloud.com>";
    const apiKey = "<your-api-key>";
  
    const url = `wss://${tenant}/app/${appId}`;
  
    const session = enigma.create({
      schema,
      createSocket: () =>
        new WebSocket(url, {
          headers: { Authorization: `Bearer ${apiKey}` },
        }),
    });
  
    // bind traffic events to log what is sent and received on the socket:
    session.on("traffic:sent", (data) => console.log("sent:", data));
    session.on("traffic:received", (data) => console.log("received:", data));
  
    // open the socket and eventually receive the QIX global API, and then close
    // the session:
        // open the socket and eventually receive the QIX global API, and then close
    // the session:
    try {
      const global = await session.open();
      console.log("You are connected!");
      const doc = await global.openDoc(appId, "", "", "", false)
      const sheets = await doc.getObjects({qTypes: ["sheet"]})
      for (const sheetMeta of sheets) {
        console.log(`Title: "${sheetMeta.qMeta.title}" ID: "${sheetMeta.qInfo.qId}" published: ${sheetMeta.qMeta.published}`)
        const sheet = await doc.getObject(sheetMeta.qInfo.qId)
        if (!sheetMeta.qMeta.published) {
          await sheet.publish()
          console.log(`Published ${sheetMeta.qMeta.title}`)
        }
      }
      await session.close();
      console.log("Session closed!");
    } catch (err) {
      console.log("Something went wrong :(", err);
    }
  })();

 

 This example works for me, it also shows how to retrieve the sheets and how they can be published/unpublished.

I would however recommend using the `qix` package from `qlik/api`: https://www.npmjs.com/package/@qlik/api

It is a bit easier to use and adds some functionality on top off enigma. It is also written in TypeScript which enables better code-completion and help if you're using an IDE. Here is the equivalent example using `qlik/api`:

 

import qix from "@qlik/api/qix";

(async () => {
  const session = qix.openAppSession({
    hostConfig: {
      apiKey: "<api-key>",
      host: "<https://tenant.region.qlikcloud.com>",
    },
    appId: "<app-id>",
  })
  const app = await session.getDoc();
  const sheets = await app.getObjects({qTypes: ["sheet"]})
  for (const sheetMeta of sheets) {
    const id = sheetMeta.qInfo.qId
    // @Ts-expect-error
    const { title, published } = sheetMeta.qMeta
    console.log(`Title: "${title}" ID: "${id}" published: ${published}`)
    const sheet = await app.getObject(id)
    if (!published) {
      await sheet.publish()
    }
 }
 session.close() 
})()

 

 

I've updated the code examples to also include how to publish a generic object. Note the casing of the "publish" function and that you have to fetch the generic object first.

Also worth noting, if you use `@qlik/api`with e.g. VSCode you get information about the available functions and what parameters they take for each object which simplifies writing code quite a lot.

View solution in original post

6 Replies
Øystein_Kolsrud
Employee
Employee

I don't think there is a REST endpoint available to publish app objects. If I remember correctly you have to do this through the engine API. This is the endpoint to use in that case:

https://qlik.dev/apis/json-rpc/qix/genericobject/#publish

nilshapavan
Employee
Employee
Author

@Øystein_Kolsrud I tried to using https://qlik.dev/toolkits/enigma-js/

 

 

(async () => {
  const enigma = require("enigma.js");
  const schema = require("enigma.js/schemas/12.612.0");
  const WebSocket = require("ws");

  // replace with your information
  const appId = "<app-id>";
  const tenant = "<your-tenant.qlikcloud.com>";
  const apiKey = "<your-api-key>";

  const url = `wss://${tenant}/app/${appId}`;

  const session = enigma.create({
    schema,
    createSocket: () =>
      new WebSocket(url, {
        headers: { Authorization: `Bearer ${apiKey}` },
      }),
  });

  // bind traffic events to log what is sent and received on the socket:
  session.on("traffic:sent", (data) => console.log("sent:", data));
  session.on("traffic:received", (data) => console.log("received:", data));

  // open the socket and eventually receive the QIX global API, and then close
  // the session:
  try {
    const global = await session.open();
    console.log("You are connected!");
    const doc = await global.openDoc(appId);
     // Fetch the list of sheets
    const sheetList = await doc.getObject("SheetList");
    console.log('Sheet List:', sheetList);
      
    await session.close();
    console.log("Session closed!");
  } catch (err) {
    console.log("Something went wrong :(", err);
  }
})();

 

 

 but  `global.openDoc(appId);`  is not working. server is not responding with any errors or success messages.

 

Øystein_Kolsrud
Employee
Employee

I'm not really the best person to answer questions regarding JavaScript, but there are some examples available for how to use enigma.js here: https://github.com/qlik-oss/enigma.js/tree/master/examples

dxa
Employee
Employee

Hi! I think that the problem is that "global.openDoc" takes more parameters than just the ID of the app.

 

(async () => {
    const enigma = require("enigma.js");
    const schema = require("enigma.js/schemas/12.612.0");
    const WebSocket = require("ws");
  
    // replace with your information
    const appId = "<app-id>";
    const tenant = "<your-tenant.qlikcloud.com>";
    const apiKey = "<your-api-key>";
  
    const url = `wss://${tenant}/app/${appId}`;
  
    const session = enigma.create({
      schema,
      createSocket: () =>
        new WebSocket(url, {
          headers: { Authorization: `Bearer ${apiKey}` },
        }),
    });
  
    // bind traffic events to log what is sent and received on the socket:
    session.on("traffic:sent", (data) => console.log("sent:", data));
    session.on("traffic:received", (data) => console.log("received:", data));
  
    // open the socket and eventually receive the QIX global API, and then close
    // the session:
        // open the socket and eventually receive the QIX global API, and then close
    // the session:
    try {
      const global = await session.open();
      console.log("You are connected!");
      const doc = await global.openDoc(appId, "", "", "", false)
      const sheets = await doc.getObjects({qTypes: ["sheet"]})
      for (const sheetMeta of sheets) {
        console.log(`Title: "${sheetMeta.qMeta.title}" ID: "${sheetMeta.qInfo.qId}" published: ${sheetMeta.qMeta.published}`)
        const sheet = await doc.getObject(sheetMeta.qInfo.qId)
        if (!sheetMeta.qMeta.published) {
          await sheet.publish()
          console.log(`Published ${sheetMeta.qMeta.title}`)
        }
      }
      await session.close();
      console.log("Session closed!");
    } catch (err) {
      console.log("Something went wrong :(", err);
    }
  })();

 

 This example works for me, it also shows how to retrieve the sheets and how they can be published/unpublished.

I would however recommend using the `qix` package from `qlik/api`: https://www.npmjs.com/package/@qlik/api

It is a bit easier to use and adds some functionality on top off enigma. It is also written in TypeScript which enables better code-completion and help if you're using an IDE. Here is the equivalent example using `qlik/api`:

 

import qix from "@qlik/api/qix";

(async () => {
  const session = qix.openAppSession({
    hostConfig: {
      apiKey: "<api-key>",
      host: "<https://tenant.region.qlikcloud.com>",
    },
    appId: "<app-id>",
  })
  const app = await session.getDoc();
  const sheets = await app.getObjects({qTypes: ["sheet"]})
  for (const sheetMeta of sheets) {
    const id = sheetMeta.qInfo.qId
    // @Ts-expect-error
    const { title, published } = sheetMeta.qMeta
    console.log(`Title: "${title}" ID: "${id}" published: ${published}`)
    const sheet = await app.getObject(id)
    if (!published) {
      await sheet.publish()
    }
 }
 session.close() 
})()

 

 

I've updated the code examples to also include how to publish a generic object. Note the casing of the "publish" function and that you have to fetch the generic object first.

Also worth noting, if you use `@qlik/api`with e.g. VSCode you get information about the available functions and what parameters they take for each object which simplifies writing code quite a lot.

nilshapavan
Employee
Employee
Author

after changing parameters it's working. 

 

 

global.openDoc(appId, "", "", "", false)

 

 

 However I'm not able to publish a sheet .

I want to publish a sheet from a list of sheets.I was able to get firstsheet from the list

 

 

sheet.publish() // not working

 

Also tried as per doc - https://qlik.dev/apis/json-rpc/qix/genericobject/#publish

 await genericObject.Publish({})
try {
    const global = await session.open();
    console.log("You are connected!", global);

    console.log("Methods available on global:", Object.getOwnPropertyNames(global));

    const doc = await global.openDoc(appId, "", "", "", false);
    console.log(`APP METADATA: ${doc}`);

    console.log("Methods available on doc:", Object.getOwnPropertyNames(doc));

    // Fetch the list of sheets
    //const sheetList = await doc.getObject("SheetList");
   const sheets = await doc.getObjects({qTypes: ["sheet"]});
    console.log('Sheet List:', sheets);
   
    const firstSheet = sheets[0]; // Get the first sheet in the list
    console.log("First Sheet Metadata:", firstSheet.qInfo);

    console.log(`First Sheet Title: "${firstSheet.qMeta.title}"`);
    console.log(`First Sheet ID: "${firstSheet.qInfo.qId}"`);
    console.log(`First Sheet Published: ${firstSheet.qMeta.published}`);

    const sheetId = firstSheet.qInfo.qId;  
    console.log(`Selected sheet ID: ${sheetId}`);

    const sheetObject = await doc.getObject(sheetId);
    console.log(`Selected sheet object:`,sheetObject );
    const result = await sheetObject.Publish({}); // not working
    
    await session.close();
    console.log("Session closed!");
  } 

 Please let me know how to publish a sheet from a list of sheets.

dxa
Employee
Employee

The publish function is called "publish" not with a capital P. It also doesn't take any arguments. I'll update the example I posted previously to include a publish call.