Why do I get "AJS.MacroBrowser is undefined"?

Hi

I’m following the tutorial about “hidden macro parameters”: Including information in your macro for the Macro Browser

I’ve managed to add a new parameter and the following Javascript file gets deployed when I upload my plugin:

AJS.MacroBrowser.setMacroJsOverride("example-formatting", {
    fields: {
        string: {
            "willbehidden": function (param) {
                var parameterField = AJS.MacroBrowser.ParameterFields["_hidden"](param, {});
                if (!parameterField.getValue()) {
                    parameterField.setValue('hidden field value');
                }
                return parameterField;
            }
        }
    }
});

However, when I pick my macro from the macro browser the console keeps giving me such an error:

Failed to run init function: AJS.MacroBrowser is undefined 
function () TypeError: AJS.MacroBrowser is undefined

I’ve also tried to wrap the JS code into this block, which is not included in the tutorial code, but elsewhere it’s described as being mandatory:

AJS.toInit(function(){
	// above code
});

However, this does not resolve the issue, even though AJS.MacroBrowser is available to me in the console. Purging the browser cache doesn’t help. I’m totally stuck and would appreciate any help.

Regards
Dominik

I’m a bit further, it seems that the MacroBrowser dependency in the web-resource is really crucial (and I somehow messed that up):

   <dependency>confluence.editor.actions:editor-macro-browser</dependency>
    <context>macro-browser</context>

Now the error is gone, but the JS code has zero effects :frowning: I’d expect the hidden field to actually get hidden, but it’s still there. Also, I would expect the field to get hidden if I just execute the whole command in the console, but nothing happens.

Oh! This is so frustrating :angry:
I wasted hours only to find out that AJS.MacroBrowser.setMacroJsOverride(macro, func) takes the xhtml-macro name as its first argument, not the key!

Hi @dokaspar

May I know how you solved the undefined issue of AJS.MacroBrowser ? I have the same problem, but it only occurs in Confluence 8.0.

@Leon We are also facing the same issue in confluence 8.0. Found any solution ?

Hi @krishnashah

We haven’t found the root cause, but in case you refer to the context of macro-browser like this → requireResourcesForContext("macro-browser")(in my case, I refer this in velocity templates). Probably you can try to delete it and just call the AJS.MacroBrowser as it has been exported globally. My plugin works again after I stop requiring the macro-browser context, but still figuring out why is that.

2 Likes

Hi @Leon

I’m using AJS.MacroBrowser in one of the custom plugin that we built. It was working fine till confluence 7.19.8 version. We just upgraded our instance to 8.5.2 , started facing the same issue .

Failed to run init function: AJS.MacroBrowser is undefined 
function () TypeError: AJS.MacroBrowser is undefined

Do you know any workaround for this as well ?

Thanks & Regards
Nishant

Hey @Nishantupadhyay,

As per my knowledge, we no longer need to import the macro-browser context such as requireResourcesForContext("macro-browser") due to AJS.MacroBrowser has been exported globally. I tried it last time at Confluence 8.0 but I haven’t try it on 8.5.2.

If you import the macro-browser explicitly, you can try to remove it and see if it works.

Thanks
Leon Kong.

Hi @Leon

Thanks for the reply and looking into it. I’m not importing the macro-browser explicitly… I’m directly calling AJS.MacroBrowser function in my JS file but still error exists. It was working fine in 7.19.8 but after 8.5.2 upgrade ,I’m getting this error.

This is my Plugin JS code …

(
    function($) {

        var custommacro = function() {};
        var fileurl;
        var frameElement;
        console.log('inside cjs file');

        custommacro.prototype.fields = {
            "string": {
                "code": function(param) {
                    var parameterField = AJS.MacroBrowser.ParameterFields["_hidden"](param, {});
                    console.log('parameterField:' + parameterField)
                    if (!parameterField.getValue()) {
                        parameterField.setValue('');
                    }
                    return parameterField;
                },
                "url": function(param, options) {
                   console.log('inside fileurl funcation');
                   var paramDiv = AJS.$(Confluence.Templates.MacroBrowser.macroParameter());
                   paramDiv.empty();
                   var input = AJS.$("#macro-param-div-url", paramDiv);
                   //Calling a function which returns the iframe and append it .. 
                return new AJS.MacroBrowser.Field(paramDiv, input, options);
                }
            }
        };

        custommacro.prototype.beforeParamsSet = function(selectedParams, macroSelected) {
            fileurl = selectedParams.url;
            console.log('url:' + fileurl);
            return selectedParams;
        };

        custommacro.prototype.beforeParamsRetrieved = function(params) {
            params.fileurl = $("#macro-param-url").val();
            console.log('fileurl' + fileurl);
            console.log('insidebeforeparamretrieved');
            return params;
        };

        AJS.MacroBrowser.setMacroJsOverride("insert-link-file", new custommacro());

    })(AJS.$);

Here is my atlassian-plugin.xml file …

 <web-resource key="myConfluenceMacro-resources" name="myConfluenceMacro Web Resources">
        <dependency>com.atlassian.auiplugin:ajs</dependency>
        <resource type="download" name="myConfluenceMacro.css" location="/css/myConfluenceMacro.css"/>
        <resource type="download" name="custom-editorup.js" location="/js/custom-editorup.js" /> <resource type="download" name="images/" location="/images"/>
        <dependency>confluence.editor.actions:editor-macro-browser</dependency>
        <context>myConfluenceMacro</context>
        <context>atl.general</context>
    </web-resource>

Do you see any issue in above code ?

Thanks & Regards
Nishant

Are you using AMD? Global variables have been removed, IIRC with version 8.

require(['ajs'], function (AJS) {
    "use strict";
// ... your code here ....
}

Maybe this is one issue?

@rr1 Hi Robert,

Thanks for looking into it.

I’ve shared the code in above post.

I’m not using require JS in my code. Do you mean going forward I’ve to use required.JS in confluence 8.5 version onwards ? Could you please elaborate more on the issue you see in the code ? I’m newbie in JS programming…

Thanks & Regards
Nishant

Hi @Nishantupadhyay,

sorry, I assume I was wrong. I read “Editor” and thought that this may an issue with the removal of JS Global Variables (see Preparing for Confluence 8.0 | Confluence Data Center and Server 8.6 | Atlassian Documentation, " Removal of Editor javascript global variables"), But you are referring to “MacroBrowser”.

Also the original author has no issues with modules. So my reference probably won’t solve your problem.

In case you want to read more about AMD (Asynchronous Module Definition), this may be a good way to start: What is AMD Module key?. I also asked a couple of questions regarding AMD on Confluence Developer and got many answers as part of this thread: Preparing for Confluence 8.0 - EAP coming soon - #25 by rr1

Cheers,
Robert