Skip to content

Latest commit

 

History

History
158 lines (101 loc) · 6.93 KB

upgrade-from-1.md

File metadata and controls

158 lines (101 loc) · 6.93 KB

Upgrading from Naja 1.x

Naja 2.0 has introduced a number of BC breaks to keep it in sync with modern standards and APIs. This section of the docs describes all of these changes and the way to upgrade.

Naja 2.0 uses Fetch API

The most notable, and at the same time the most internal change is that Naja now directly uses Fetch API to dispatch requests. As a result, there is no longer an XMLHttpRequest, which led to a change in the contents of most of Naja's events: they no longer reference the xhr, and instead hold the Request instance, as well as the Responsewhere possible.

Please refer to the Events reference for more information about the new events.

!> Pay special attention to success and complete events. In 1.x, these events held the response payload in event.response. In 2.0, event.detail.response holds the Fetch API's Response instance, while the response payload is accessible via event.detail.payload.

The interaction event has moved

The interaction event has moved to where it belongs better, the UIHandler. Luckily, the migration path is quite straight-forward: just add .uiHandler. In other words, change this:

naja.addEventListener('interaction', interactionHandler);

to this:

naja.uiHandler.addEventListener('interaction', interactionHandler);

The load event has been removed

The load event has been removed because it didn't fit that nicely into the set of events that Naja dispatches during the request's lifecycle. Besides, it has already had better replacements for quite a long time.

Probably its most dominant use case has been to reinitialize scripts after updating snippets, so that e.g. social media widgets from snippets would come alive. The SnippetHandler dispatches a pair of events for each updated snippet; you can use these to achieve the same behaviour, and possibly gain a little performance boost, because you can restrict the reinitialization only to the snippet and its subset of DOM.

Consider the following example using Twitter's JavaScript API:

Before:

naja.addEventListener('load', () => {
    twttr.widgets.load();
});

After:

naja.snippetHandler.addEventListener('afterUpdate', (event) => {
    twttr.widgets.load(event.detail.snippet);
});

For other use cases, the load event is dispatched during Naja's initialization – which can be replaced by the initevent or by calling the code directly during initialization –, and then after every request, be it successful or not, which can be replaced by the complete event.

All events are proper CustomEvents

Naja and its event-dispatching components now properly implement the EventTarget interface. Also, events are no longer plain objects duck-typed to resemble events; events now make use of the CustomEvent API. The practical consequence is that event-specific data have moved from the event itself to its detail attribute. The following code:

naja.addEventListener('before', (event) => {
    console.log(event.request);
});

must therefore be rewritten to this:

naja.addEventListener('before', (event) => {
    console.log(event.detail.request);
});

Extensions API is refactored

The extensions API in Naja 1.0 had been designed in a bit slapdash manner. Well, more like half-baked than designed. In Naja 2.0, the entry point of an extension has moved from its constructor to the initialize()method. That's where extensions receive the instance of Naja and where they should bind their event listeners. The extension can utilize its constructor however it needs, or not at all.

As a result, you no longer register the extension's constructor and you no longer have to pass arguments through Naja. Extensions are registered as instances and initialized later by Naja through the initialize() method.

Before:

class LoaderExtension {
    constructor(naja, loaderSelector) {
        this.loader = document.querySelector(loaderSelector);
        naja.addEventListener('start', () => { /* show this.loader */ });
        naja.addEventListener('complete', () => { /* hide this.loader */ });
    }
}

naja.registerExtension(LoaderExtension, '#loader');

After:

class LoaderExtension {
    constructor(loaderSelector) {
        this.loader = document.querySelector(loaderSelector);
    }

    initialize(naja) {
        naja.addEventListener('start', () => { /* show this.loader */ });
        naja.addEventListener('complete', () => { /* hide this.loader */ });
    }
}

naja.registerExtension(new LoaderExtension('#loader'));

As an added bonus, extensions no longer have to be "classes". Even a plain object is fine as long as it implements the initialize() method:

const loggerExtension = {
    initialize(naja) {
        naja.addEventListener('complete', (event) => console.log(event.detail));
    }
};

naja.registerExtension(loggerExtension);

Options are no longer read from response payload

Naja 1.7.0 has deprecated the support for reading some options from the response payload, namely forceRedirect and replaceHistory. This mechanism is now entirely removed and the only way you can configure these is through the requestoptions or via respective data-atrributes. Please refer to the docs of RedirectHandler and HistoryHandler for more information.

Farewell Internet Explorer

Naja 2.0 has dropped support for Internet Explorer. Naja is no longer tested on this browser and therefore cannot guarantee that it works properly. If you still need to support IE, you can always stick with the 1.x version.

In theory, it might be possible to make Naja 2.0 work on IE by including polyfills for:

Note that this list might not be complete.

Considerations for third-party extensions authors

If you develop and maintain your own extension for Naja and distribute it as an open-source software, probably the best thing to do is to bump the required version of Naja in your extension's package.json and release a new version that supports Naja 2.0 only.

If you for some reason need or want to support both versions of Naja and don't want to maintain two versions at once, you can list both version ranges of Naja in your extension's package.json (for example like this: ^1.0 || ^2.0) and write code in a way that detects the version of Naja and uses the appropriate available APIs based on the version.

To facilitate this, Naja as of 2.0 exposes its version number in a field named VERSION:

if (naja.VERSION >= 2) {
    // we have >=2.0
}