9

I am trying to create a FF AddOn that brings some XML data from a website. But I can't find a way to parse my RESPONSE. First I used DOMParser but I get this error:

ReferenceError: DOMParser is not defined.

Someone suggested to use XMLHttpRequest, because the parsing is done automatically but then I get this other error:

Error: An exception occurred. Traceback (most recent call last):
File "resource://jid0-a23vmnhgidl8wlymvolsst4ca98-at-jetpack/api-utils/lib/cuddlefish.js", line 208, in require let module, manifest = this.manifest[base], requirer = this.modules[base]; TypeError: this.manifest is undefined

I really don't know what else to do. I must note that I am using the AddOn Builder to achieve this.

Below the code that doesn't seem to work.

Option 1:

exports.main = function() {

require("widget").Widget({
    id: "widgetID1",
    label: "My Mozilla Widget",
    contentURL: "http://www.mozilla.org/favicon.ico",
    onClick: function(event) {

    var Request = require("request").Request;
    var goblecontent = Request({
      url: "http://www.myexperiment.org/search.xml?query=goble",
      onComplete: function (response) {
        var parser = new DOMParser(); 
        var xml = parser.parseFromString(response.text, "application/xml");  

        var packs = xml.getElementsByTagName("packs");
        console.log(packs);
      }
    });

    goblecontent.get();

    }
});

};

Option 2:

exports.main = function() {
    require("widget").Widget({
        id: "widgetID1",
        label: "My Mozilla Widget",
        contentURL: "http://www.mozilla.org/favicon.ico",
        onClick: function(event) {

            var request = new require("xhr").XMLHttpRequest();
            request.open("GET", "http://www.myexperiment.org/search.xml?query=goble", false);
            request.send(null);  

            if (request.status === 200) {  
              console.log(request.responseText);  
            }  
        }
    });
};
Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
kriztean
  • 229
  • 3
  • 13

2 Answers2

14

DOMParser constructor isn't defined in the context of SDK modules. You can still get it using chrome authority however:

var {Cc, Ci} = require("chrome");
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);

nsIDOMParser documentation.

That said, your approach with XMLHttpRequest should work as well. You used the new operator incorrectly however, the way you wrote it a new "require object" is being created. This way it should work however:

var {XMLHttpRequest} = require("xhr");
var request = new XMLHttpRequest();

Please consider using an asynchronous XMLHttpRequest object however, use request.onreadystatechange to attach your listener (the xhr module currently doesn't support other types of listeners or addEventListener).

Paul Fournel
  • 10,807
  • 9
  • 40
  • 68
Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • 1
    +1 for the sake of your users please avoid synchronous network access of any kind! – therealjeffg Feb 07 '12 at 13:25
  • @canuckistani: Now if only `xhr` implemented proper `onload` and `onevent` properties ;) Web developers might be used to `onreadystatechange` but I consider it an ugly solution. – Wladimir Palant Feb 07 '12 at 14:12
  • @Wladimir Palant. The DOMParse solution worked great. However the XMLHttpRequest solution threw at me the same error message. I ended up doing something similar to what you recommended me with DOMParse: `var {Cc, Ci} = require("chrome"); var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);` and it worked!. Thank you – kriztean Feb 07 '12 at 16:03
  • @user1042066: Please don't do this. `xhr` module makes sure that the request is automatically aborted if your extension is uninstalled/disabled - the regular `XMLHttpRequest` won't do anything like this. – Wladimir Palant Feb 07 '12 at 16:07
  • @Wladimir Palant . I won't do that sorry. I found my mistake I copied the code you posted blindly without removing the `new` operator. Now it worked! thank you – kriztean Feb 07 '12 at 16:19
  • @kriztean: Ouch... You are right, the SDK consistently uses factory functions instead of the `new` operator and I completely missed that. Fixed my answer now. – Wladimir Palant Feb 07 '12 at 20:48
  • From the [xhr module docs](https://addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/api-utils/xhr.html): _XMLHttpRequest(): Creates an XMLHttpRequest. This is a constructor, so its use should always be preceded by the new operator._ I have tested it and for me it doens't work if I don't use the new keyword. I get a _TypeError: null is not extensible_ error in xhr.js _this._req = req_. So correct way: `var xhr = require("xhr"); var req = new xhr.XMLHttpRequest();` – cprcrack Oct 26 '12 at 13:12
  • 1
    @cprcrack: You are right, I fixed the code. I think that this changed since the answer was written (it's an internal API so it can change at any time). – Wladimir Palant Oct 26 '12 at 22:15
3

If you use XMLHttpRequest (available via the xhr module) you can easily avoid the use of DOMParser. Bellow I provide an example supposing request is an XMLHttpRequest object which request is successfully completed:

Instead of:

var parser = new DOMParser(); 
var xmlDoc = parser.parseFromString(request.responseText, "application/xml");  

Use:

var xmlDoc = request.responseXML;  

An then you can:

var packs = xmlDoc.getElementsByTagName("packs");
console.log(packs);

Or whatever.

cprcrack
  • 17,118
  • 7
  • 88
  • 91