Superagent: expose xml as res.body

Created on 6 May 2013  路  14Comments  路  Source: visionmedia/superagent

never thought I'd say this, but for amazon shit it's necessary

Browser

Most helpful comment

I got it working with this, so I guess it's already supported.

var request = superagent.get(url);
request.buffer();
request.type('xml');
request.end(function(res) {    
    console.log(res.text);
});

All 14 comments

In an attempt to use superagent with an XML datasource (and have res.body reflect the XML content response), I was using xml2js as shown below. Although the parser seems to be working and myParse outputs the correct result, the callback on the request seems to be getting called before the parser 'end's. i.e. request.get outputs undefined (since parser is still at work) and then the parser outputs the correct result. Any ideas on what might be happening here? Thank you.

var parser = new xml2js.Parser();

function myParse (res, fn) {
  res.text = '';
  res.setEncoding('utf8');
  res.on('data', function(chunk){ 
      res.text += chunk; });
  res.on('end', function ()
    {
    parser.parseString(res.text, function (err, result) {
      if (err)
        fn(err);
      else
      {
            fn(null, JSON.stringify(result));
      }
      });

    });
}

request.get(url)
    .set('Content-Type', 'application/xml; charset=utf8') 
    .parse(myParse)
    .end(function(err, res){
          if (err) console.log("Could not access database.");
         else console.log("Output :", res.data);
                });

What I'm noticing may be related to: https://github.com/visionmedia/superagent/issues/244

I got it working with this, so I guess it's already supported.

var request = superagent.get(url);
request.buffer();
request.type('xml');
request.end(function(res) {    
    console.log(res.text);
});

@visionmedia you still want this?

I need to work with some XML APIs :-(

I would like to help get this done. I just need some direction. My skills are intermediate at best, I need more practice. This looks like a good problem to solve. What can I do to help? Is there a plan for this?

Thanks

Todd

I just published a tiny module that converts xml in res.text to JSON in res.body

https://github.com/toddgeist/superagent-xml2jsparser

I'm -1 in core and maybe adding a little cleaner way to define new parsers. XML is a good example actually... some people will want/need a certain XML parser for various legit reasons (e.g libxml vs xml-parser vx xyz) and then on top of that some people will want the XML to be parsed into JSON and others will want the XML document and so on.

Perhaps something like:

var request = require('superagent');
var parse = require('xml-parser');

request.parsers.set('text/xml', parse);

request.get('/', function (res){
  res.body // << whatever xml-parser gives you (an object I think)
});

or

var request = require('superagent');
var libxml = require('libxmljs');

request.parsers.set('text/xml', libxml.parseXmlString);

request.get('/', function (res){
  res.body // << instanceof XmlDocument
});

why not as a plugin instead? lets do this right.

Would it be possible on the form request.use(parser) ? Maybe like var agent = request.agent(); agent.use(parser); and then only use that agent for the XML requests

Actually there is already a way... otherwise I think I am confusing the feature request here.

superagent.parse['application/xml'] = function(res, fn){
   fn(null, customParserHere(res.text));
};

https://github.com/visionmedia/superagent/blob/master/lib/node/index.js#L102-L104

I was able to use the solution from @laurilarjo, so Thanks!
For those who want to use that solution as well, there's a little typo in his code. Don't forget the error comes first in the parameter list for the callback function on end.

var request = superagent.get(url);
request.buffer();
request.type('xml');
request.end(function(err, res) {    
    console.log(res.text);
});

or the 'shorter' version:

const request = superagent.get(url)
 .buffer()
 .type('xml')
 .end((err, res) => {    
    console.log(res.text);
});

I was able to use solution from @laurilarjo, @PWani and @gjohnson, thx all!
The key point is enable buffering with .buffer(), the .type() refers to the request body and useless if you are only interested on the response body:
```var url = 'http://localhost:3000';
var superagent = require('superagent');
var xml2js = require('xml2js');
function myParse (res, cb) {
res.text = '';
res.on('data', chunk => res.text += chunk);
res.on('end', () => xml2js.parseString(res.text, cb));
}
superagent.parse['application/xml'] = myParse;
superagent.get(url).buffer().end((err, res) => console.dir(res.body, {depth: null});

@susumuasaga, your solution worked for me!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vlinder picture vlinder  路  8Comments

tj picture tj  路  9Comments

ropez picture ropez  路  7Comments

kornelski picture kornelski  路  4Comments

djizco picture djizco  路  5Comments