Search code examples
javascriptnode.jsxml2js

Got different answer from a return of a function


I'm blocked since few hours now, I wish somebody can help me figure out what I do wrong. This whole code is to get a json response from an API. I want to understand what are my errors, so please, explain a little ! ;)

const fetch = require('node-fetch');
const Bluebird = require('bluebird');
fetch.Promise = Bluebird;
const xml2js = require('xml2js');

module.exports = {

    getImage : async function (tag, random){
        
        let url = "anApiLink" + tag;

        if(random != null) url = "anApiLink" + tag + "&id=" + random;
        
        const get_data = async url => {
            
            try {
                const response = await fetch(url);
                
                if(! response.ok) return new Error("Erreur lors de la récupération de l'image : " + response.statusText);
                
                const text = await response.text();



                const xmlToJson = await xml2js.parseString(text, (err, result) => {
                    
                    if(err) throw err;

                    const json = JSON.stringify(result, null, 4);  

                    return json;
                });
                
                console.log(xmlToJson);
                return xmlToJson;

            } catch (err) {
                console.error(err);
            }
        };

        return get_data(url);
            
    }
}

My json const is what I want to return from the global function (get_data), and it's an actual good json answer. With my final return, I actually get what's below.

From my console.log() :

{
  comment: '',
  sgmlDecl: '',
  textNode: '',
  tagName: '',
  doctype: '',
  procInstName: '',
  procInstBody: '',
  entity: '',
  attribName: '',
  attribValue: '',
  cdata: '',
  script: '',
  c: '',
  q: '',
  bufferCheckPosition: 65536,
  opt: { trim: false, normalize: false, xmlns: false, lowercase: undefined },
  looseCase: 'toUpperCase',
  tags: [],
  sawRoot: false,
  closedRoot: false,
  closed: false,
  error: null,
  tag: null,
  strict: true,
  noscript: true,
  state: 0,
  strictEntities: undefined,
  ENTITIES: {},
  attribList: [],
  trackPosition: true,
  column: 0,
  line: 0,
  position: 0,
  errThrown: false,
  onerror: [Function],
  onend: [Function],
  ended: true,
  onopentag: [Function],
  onclosetag: [Function],
  ontext: [Function],
  oncdata: [Function],
  startTagPosition: 781
}

Thanks for the help.


Solution

  • Salut, I didn't even realize at first that I was reading french in your code... Your problem seemed to be related to that library you're using, xml2js. I took a look at their docs, and maybe this may help you.

    The function itself does not return the result, but you can get it in the callback, that's the reason why you're logging this weird object. You could create a separate var to store the result, but I have a better solution.

    If you want to use promises, I found this in the docs, and this in the source code about parseStringPromise, and I think that's what you want. The source code indicates that the result is returned as a Promise here.

    In short, what you return in the callback isn't returned by parseString. This is what xmlToJson should be to act as intended.

    // Not tested. I might have made an error about the location of 'then', not sure.
    const xmlToJson = await xml2js.parseStringPromise(text)
      .catch(e => throw e)
      .then(r => JSON.stringify(r, null, 4))