Search code examples
javascriptjqueryajaxfetch-apirivescript

How to convert Ajax to Fetch API in JavaScript?


So I am using the JavaScript port of RiveScript which uses ajax and of course I don't want to use jQuery anymore. There is only one line ajax and I want to change it to the new Fetch API.

**FYI: You can see the ajax code in line 1795 of the CDN.**

So here's the original code:

return $.ajax({
    url: file,
    dataType: "text",
    success: (function(_this) {
        return function(data, textStatus, xhr) {
            _this.say("Loading file " + file + " complete.");
            _this.parse(file, data, onError);
            delete _this._pending[loadCount][file];
            if (Object.keys(_this._pending[loadCount]).length === 0) {
                if (typeof onSuccess === "function") {
                    return onSuccess.call(void 0, loadCount);
                }
            }
        };
    })(this),
    error: (function(_this) {
        return function(xhr, textStatus, errorThrown) {
            _this.say("Ajax error! " + textStatus + "; " + errorThrown);
            if (typeof onError === "function") {
                return onError.call(void 0, textStatus, loadCount);
            }
        };
    })(this)
});

and here's what I tried so far using the Fetch API:

return fetch(file, {
        dataType: "text"
    })
    .then(function(_this) {
        return function(data, textStatus, xhr) {
            _this.say("Loading file " + file + " complete.");
            _this.parse(file, data, onError);
            delete _this._pending[loadCount][file];
            if (Object.keys(_this._pending[loadCount]).length === 0) {
                if (typeof onSuccess === "function") {
                    return onSuccess.call(void 0, loadCount);
                }
            }
        };
    })
    .catch(function(_this) {
        return function(xhr, textStatus, errorThrown) {
            _this.say("Ajax error! " + textStatus + "; " + errorThrown);
            if (typeof onError === "function") {
                return onError.call(void 0, textStatus, loadCount);
            }
        };
    })

The app code:

var bot = new RiveScript();

bot.loadFile("./brain.rive", loading_done, loading_error);


function loading_done (batch_num) {
    console.log("Batch #" + batch_num + " has finished loading!");

    bot.sortReplies();

    var reply = bot.reply("local-user", "Hello, bot!");
    console.log("The bot says: " + reply);
}

function loading_error (error) {
    console.log("Error when loading files: " + error);
}

Using the Fetch API, I'm not seeing any error now though I'm also not seeing any error or success messages.

Am I missing something here?


Solution

  • The fetch init object doesn’t have a dataType key.

    To indicate you want plain text back, add an Accept: text/plain header to the request:

    fetch(file, {
        headers: {
          "Accept": "text/plain"
        },
      })
    

    And the fetch call returns a promise that resolves with a Response object, and that Response object provides methods that resolve with text, JSON data, or a Blob — which means the basic form for handling the response from your fetch(…) call is like this:

    fetch(file, {
      headers: {
        "Accept": "text/plain"
      },
    })
    .then(response => response.text())
    .then(text => {
      // Do something with the text
    })
    

    So you need to take the existing code in the question and fit it into that form.