AJS.params has been deprecated in AUI 9.0

What is the replacement function developers should use before this is removed?

Hi @mr.chris.kent,

I can read your question in two ways:

  1. How do I send data to the UI from my plugin?
  2. I depend on <specific data> that I’m currently accessing via AJS.params… what should I do instead?

I’ll answer both, but will give a short explanation of why this is deprecated first.

Why is AJS.params going away?

The AJS.params and associated AJS.populateParameters() function were deprecated for a few reasons:

  • It’s indirect. Typically, the data is scraped from <meta/> tags in the head of the page or from specific <input type=hidden/> elements on the page. Embedding data for JS use inside HTML is awkward; not only does it require additional escaping, it also means the HTML parser spends time building DOM for elements it doesn’t need to, which slows page rendering slightly.
  • The data isn’t always there. Because the data is scraped from HTML, and because it’s possible some HTML-for-serving-data exists in the last few bytes before the closing </body> tag, the entire HTML document must finish serving before the data can be scraped and made available in AJS.params. That means you need to wait until DomContentLoaded before you can access the data.
  • It lacks ownership. The data could have come from anywhere. If a feature that put data in AJS.params were to change or be removed, it’s impossible to know if there were other consumers that relied on it being there. This leads to features breaking based on other unrelated features changing, which isn’t good for reliability.

Given these drawbacks, alternative solutions were built in to the Atlassian plugin system.

Get your data to the UI

To get data in to the UI layer in the initial HTML response, we recommend using the Data Provider capability. This API avoids the drawbacks of AJS.params:

  • It’s direct. Data is served via JSON to the client, so the HTML parser and renderer spend no time deciphering it.
  • Data will be there when you expect it. You can couple your data provider to the web-resource containing your javascript that needs the data. This guarantees that the moment your code executes, the data will be available to it via WRM.data.claim.
  • Data has ownership. When data is claimed, it cannot be claimed by other code. The data can be scoped to your code alone. If the data your feature needs changes or the feature is to be removed, nothing else will be affected, as nothing else could have depended upon the same data.

What do I do if I’m using someone else’s data from AJS.params?

I touched on data ownership in the previous point. Because the Data Provider capability encourages private ownership of data, the owner of that data now has a choice whether to expose it to downstream consumers or not. Rather than adding it to AJS.params, they would likely instead provide their own API.

As a consequence, the migration path for individual items in the AJS.params object will vary by product and by feature.

On one hand, the data you’re accessing may not have a new, “official” API to query it from. On the other hand, you may be able to send the data you need via your own Data Provider.

I hope this helps. Let me know if you have follow-up questions!

Cheers,
Daz

3 Likes

Hi Daz,

Thanks for the detailed response, I was referring to the second item, and specifically, Atlassian provided information like page-id, remote-user etc…

So are you saying that these built-in values will no longer be available to JS, even if using the AJS.Meta.get() function?

And all developers need to supply these values via API’s? This seems counter productive, because now if multiple plugins use the same atlassian meta params, then there is more network activity with each plugin calling new and different APIs to get the same data?

Curious to see if this was the intention and applies to built-in AJS params like mentioned above?

Thanks
Chris

If you’re using AJS.Meta.get(...) calls, those should continue to work. It’s only the AJS.params object that has been deprecated.

So are you saying that… all developers need to supply these values via API’s? This seems counter productive, because now if multiple plugins use the same atlassian meta params, then there is more network activity with each plugin calling new and different APIs to get the same data?

I agree that that wouldn’t make a lot of sense. For data that has utility in potentially any plugin, there is value in having a single, canonical value accessible from a known, public API. Direct use of AJS.params seems to have become an unofficial API.

While AJS.params is unfortunate due to its drawbacks, its breath of usage and lack of product-specific alternatives may have been underestimated. I’ll discuss with the team and see whether the deprecation should be reviewed.

Hope that helps,
Daz

Hi Daz,

Thanks for the reply, if AJS.Meta.get() function is the official way, then great, I do use that too.
The problem has come about because of the AUI online documentation, which made the unofficial AJS.params official. See here: Helper functions - AUI Documentation

And it was only because of this page, and the many warnings in the console, that I raised this thread.

Can I suggest that in the AUI user guide, that you guys mention that the official replacement for AJS.params is to use AJS.Meta.get(). This would have saved you and me a lot of time discussing this over a post ;).

Thanks for your time and verification, but please, I ask to have the documentation updated in line with your views and the correct API to use (which is missing). Meta.get() is a great helper function and should be documented.

Thanks
Chris

1 Like

If you want to know what you can access with AJS.Meta.get(...) as a drop in replacement for AJS.params, on any Confluence page, execute this snippet in the console for the page:

document.getElementsByTagName('meta')
  .forEach((meta) => {
    const { name, content } = meta;
    name.indexOf('ajs-') === 0 // only those starting with `ajs-` an be used
      && console.log(`AJS.Meta.get('${name.substring(4)}') ==> '${content}'`);
  });

You’ll get a list of what’s accessible from the current page.

2 Likes

You can also access the metadata directly via vanilla JS.

I.e.

document.querySelector('meta[name="ajs-is-admin"]')?.content ?? "default";
1 Like