Javascript inside Rest API Tutorial not working: Creating an admin configuration form - xproduct-admin-ui-plugin

Hello, Im trying to follow this SDK tutorial: https://developer.atlassian.com/server/framework/atlassian-sdk/creating-an-admin-configuration-form/

It runs and displays the form, but nothing get’s stored or displayed as it is submitted.

I tried following the tutorial, then I tried cloning the Git repository and atlas-run, and it behaves the same way.

This is the response from the GET request, after adding values via the form:

{
  "time": 0
}

Does anybody know how to fix this?

Edit: When I use the the PUT inside the Rest API Browser, the Rest API browser does display the results. So it seems that the Javascript in the tutorial is not doing anything. I tried adding console logs in every part of the Javascript file xproduct-admin-ui-plugin.js, but it does not seem to load at all. Nothing happens.

Edit2: So, webResourceManager is deprecated since 2014? How can I add new webresource to a servlet - #8 by M.Abdel-Mola & [JRASERVER-38808] WebResourceManager is deprecated, but its javadoc provides no reasonable replacement. - Create and track feature requests for Atlassian products.
Does anybody know how to replace this line in the tutorial then? At admin.vm:
$webResourceManager.requireResource("com.atlassian.plugins.tutorial.xproduct-admin-ui-plugin:resources")

It is currently throwing errors.

Hello Viktor2, I also encountered the same problem, how did you solve it?

Hi everyone,

I’ve run through this tutorial to review its contents. There are a few things that might go wrong when connecting everything together. Here’s what I’d suggest doing:

Before trying to find the problem

Add the following code to the bottom of the javascript file you have:

console.log('Admin form: javascript loaded');

Add the following code at the start of the updateConfig function body:

function updateConfig() {
  console.log('Admin form: running PUT to update values');
  // the rest of the function content as in the tutorial

From here, ensure your browser’s developer tools are open while you load and interact with the page, so you can see the console log statements.

I don’t see the “javascript loaded” comment

The javascript file may not be loaded on the page. You can use your browser’s developer tools to search for that console log call to confirm this.

If the file is not on the page, it is probably because the necessary web-resource was not loaded.

Open your atlassian-plugin.xml file and look for the block of code starting with <web-resource key="...". In the tutorial, this is as follows:

    <web-resource key="xproduct-admin-ui-plugin-resources" name="xproduct-admin-ui-plugin Web Resources">
        <dependency>com.atlassian.auiplugin:ajs</dependency>
        
        <resource type="download" name="xproduct-admin-ui-plugin.css" location="/css/xproduct-admin-ui-plugin.css"/>
        <resource type="download" name="xproduct-admin-ui-plugin.js" location="/js/xproduct-admin-ui-plugin.js"/>
        <resource type="download" name="images/" location="/images"/>

        <context>xproduct-admin-ui-plugin</context>
    </web-resource>

Here, the key we need to reference is xproduct-admin-ui-plugin-resources.

When using the web resource manager (WRM) to load web-resources, you must give it a “complete module key” so it can find your web-resource. A complete module key is in the form "<your-plugin-key>:<your-webresource-key>".

Using the values from the tutorial,

  • <your-plugin-key> is “com.atlassian.plugins.tutorial.xproduct-admin-ui-plugin”, and
  • <your-webresource-key> is “xproduct-admin-ui-plugin-resources”.

So altogether, the complete module key is com.atlassian.plugins.tutorial.xproduct-admin-ui-plugin:xproduct-admin-ui-plugin-resources.

In your velocity template, check that this is the value passed to the requireResource call. Using the values above, that would be:

$webResourceManager.requireResource("com.atlassian.plugins.tutorial.xproduct-admin-ui-plugin:xproduct-admin-ui-plugin-resources")`

:exclamation::exclamation: This is the most likely cause of the problem, as the tutorial’s content does not reference the correct web-resource key. I’ll raise an issue about that with the content team.

I click the “Submit” button, but I don’t see “running PUT to update values”

The updateConfig function is not being called. This in turn means the “submit” callback set up via jQuery did not work.

The most likely reason for this will be when the handler is registered. The #admin form element needs to exist on the page before jQuery can bind a handler to it. jQuery may have tried to locate the element before it was added to the page, couldn’t find it, and silently failed.

To remedy this, you should do one of two things:

  • Move the registration of the submit handler inside the document ready handler. The general shape of your code would be something like this:
    (function ($) {
      $(document).ready(function() {
        // request the config information from the server
        // ...
    
        function updateConfig() {
          // ...
        }
    
        $("#admin").on("submit", function (e) {
          e.preventDefault();
          updateConfig();
        });
      });
    })(AJS.$ || jQuery);
    
  • Use delegated event handling instead of binding explicitly to the form element.
    // Instead of doing this, which requires the 
    // element to exist by the time this code runs...
    $("#admin").on("submit", function(e) {
    
    // Bind the handler to document, then only 
    // run it when the 'submit' event fired on the `#admin` element
    $(document).on("submit", "#admin", function(e) {
    

I click the “Submit” button and I see the console message, but when I refresh, the values were not updated

Check the Network tab of your developer console. Confirm that a PUT request was made to the http://localhost:5990/refapp/rest/xproduct-admin/1.0/ URL, and check the HTTP status code for your submission was 204.

If the HTTP response was 500, the server received the values, but couldn’t understand them. The most probable reason is that the time value was not a number. Try again with a numeric value for the time field. Proper error handling is beyond the scope of what this tutorial is teaching. With that said, I think it deserves inclusion, so will see when our team could revise the content and include something for that.

If there was no PUT request, it means the updateConfig method did not run, or there was an error in the javascript. Check your browser console for errors. Since we are dealing with a form submission that refreshes the page, it may be necessary to alter your devtools config to persist console errors across page reloads.

I tried all the above, but it still isn’t working!

The best thing to do at this point would be to post your code somewhere like bitbucket or github and raise a separate community question around it.

I hope that helps!

Cheers,
Daz

4 Likes

Thanks for this post. Helped me get the plugin working.

I still don’t quite understand the overall operation of the sample plugin. When I save config properties am I saving name-value pairs? Why are the fields in this sample Name and Time? Feels like this wasn’t really explained very well in the tutorial

I’ll make an addendum to this comment to fix what was a big stumbling block for me. The value that needs to be inside your $webResourceManager.requireResource() call inside admin.vm is a formula as follows

  1. go to pom.xml and note the value of the groupId and artifiactId of your plugin
  2. go to your atlassian-plugin.xml and note that value in your web-resource element’s key.
  3. groupId + . + artifactId + : + web-resource key attribute value”

I had serious issues with this because I was using another Jira tutorial for building a money custom field as my base for this tutorial, and that tutorial has very strange values for groupId and artifactId that are redundant when used in the context this tutorial calls for

For anyone reading this: all the plugin is supposed to do is give you a config screen with a name and time field, that you can input values to that will be saved when you refresh.