Custom UI Confluence Plugin - Passing JQL to define.resolver

Hi there good people,

I have created a Custom UI Confluence Macro and currently my app is split between an index.js where my backend define.resolver methods are located and my App.js, where my frontend functions and HTML are located.

I am getting this validation error when I load my app on my Confluence site:
Error in the JQL Query Expecting operator before the end of the query. The valid operators are '=', '!=', '<', '>', '<=', '>=', '~', '!~', 'IN', 'NOT IN', 'IS' and 'IS NOT'."]

This is what my useEffect method / hook looks like in App.js:

import React, { useEffect, useState } from 'react';
import { invoke } from '@forge/bridge';

function App() {
  const [jqlData, setJqlData] = useState(null);
  const jqlQuery = 'project = Tiktok';

  useEffect(async () => {
    const data = await invoke('fetchIssuesCountWithJql', { jqlQuery });
    setJqlData(data);
    console.log(`Here is the data: ${data.total}`);
  }, []);

  return (
    <div>
      Total issues: {jqlData ? jqlData.total : '0'}
      {/* {jqlData ? JSON.stringify(jqlData) : 'Loading...'} */}
    </div>
  );
}

export default App;

And in my index.js backend, this is the ‘fetchIssuesCountWithJql’ resolver.define method:

import Resolver from '@forge/resolver';
import api, { route } from '@forge/api';

const resolver = new Resolver();

resolver.define('fetchIssuesCountWithJql', async (jqlQuery) => {
  const res = await api
    .asApp()
    .requestJira(route`/rest/api/3/search?jql=${jqlQuery}&maxResults=0`);

  const data = await res.json();
  return data;
});

I just can’t see why it complains that the JQL is invalid. If I create a standard Confluence UI Kit plugin and use exactly the same way to call the API, it works without issues. I wonder if the Custom UI template has an issue passing the JQL from the frontend to the backend.

These are the package versions I’m using from packages.json:

"dependencies": {
    "@forge/bridge": "^2.4.0",
    "@forge/resolver": "^1.4.10",
    "@forge/ui": "^1.6.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },

Any ideas would be very welcome as I am seriously stuck at the moment on this.

Thanks folks!

Hi @HendrikBonthuys
From initial glance it looks like your endpoint has spaces in it.
ie: /rest/api/3/search?jql=project = Tiktok&maxResults=0
which is an invalid request.
Can you remove the spaces in your jqlQuery variable

1 Like

Hi @QuocLieu, thanks for your reply and suggestion. I tried without spaces and it seems that has helped but sadly no data is coming back from the API. Interestingly though, if I do the exact same kind of call using the standard Confluence UK Kit template, even with the spaces, I get my data back from the API and can add it to my HTML without issues. Also in Postman, if I do the same request with spaces, I get my data returned correctly.

I’ve been having constant issues with the Custom UI template, it seems something is not quite right in how the resolver.define methods work. That has been my own experience anyway. I think sadly I will need to abandon making my own custom UI and just stick with the Confluence UI Kit although it has severe limitations in options compared to a library such as Bootstrap.

Do you know when the ability to add Cards will be added to the UI kit please? And also, the ability to change the size and colour of Text would be nice too but I see no options in the docs for that either at this time.

hi @HendrikBonthuys ,
I just noticed in your resolver that you’re not extracting jqlQuery correctly.
It should be:

resolver.define('fetchIssuesCountWithJql', async ({payload}) => {
const { jqlQuery } = payload;
...

Documentation on resolvers: https://developer.atlassian.com/platform/forge/runtime-reference/custom-ui-resolver/

If this doesn’t work can you try logging out the endpoint you’re calling just to make sure it’s constructed correctly?

UI Kit is much more limited and won’t have the customisability to add cards or change styles. I would suggest staying with custom UI if you’re looking for custom components and specific styling of elements