Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Join us in Bucharest on Sept 18th for Qlik's AI Reality Tour! 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.