xml2js issue: require is not defined


#1

I am trying to parse some XML using xml2js.

I have done the following:

meteor add peerlibrary:xml2js

In my code, in the “isClient” area, I have the following:

   console.log(results.content);

    var parseString = require('xml2js').parseString;
    var xml = results.content;
      parseString(xml, function (err, result) {
        console.log(result);
      });

When isolated, the first console.log displays the raw XML, so that’s no problem.

The problem is the following message:

require is not defined

I have tried to add Npm.require and also Meteor.require, but neither seem to work…

What can I try next?

Thanks


#2

meteor require only work on sever side, use cosmos:browserify if you want to use a npm package in client side


#3

I have added that package and still have the error:

require is not defined


#4

Looking at the docs for this package, it says:

Adding this package to your Meteor application adds xml2js object into the global scope.

So you don’t need to use require at all. Just use the global variable:

xml2js.parseString(...)

#5

I have modified my code to the following:

 var xml = results.content;
          xml2js.parseString(xml, function (err, result) {
            console.log(result);
          });

I now get the error:

TypeError: Cannot read property ‘parseString’ of undefined


#6

Looking at the package.js file, the xml2js object is exported to the server only.


#7

I have changed the code and now put more things in the server area, but I am still having a few issues. The code is now: (i have removed the appid…)

  Meteor.methods({
  'getWeather':function(city){
  var xmlData = Meteor.http.call('GET', 'http://api.openweathermap.org/data/2.5/weather?q=' + city + '&mode=xml&appid=***************************************');
  // then parse the xml
  //var parseString = require('xml2js').parseString;
  console.log("raw XML data: "+xmlData.content);
  xml2js.parseString(xmlData, function (err, result) {
  console.log(result);
  //return xmlData;
  });
  }
  })

And I am getting an “undefined” error in the server console when I use the xml2js command…

At least I have learned about using methods and know more about client/server in meteor:)


#8

Has any one got any ideas for this one?


#9

I’ve successfully used peerlibrary:xml2js in one of my projects. You say you get an undefined error in the server console: can we see that error, please?


#10

it’s not require(‘xml2js’).parseString; its xml2js.parseString; (and make sure its server only)

also i recommend use xml3js.parseStringSync to avoid callbacks


#11

Yes! got it going now! Thanks. Now I just have to work out how to wrangle to JSON:)

How do I reference the JSON object? I tried:

var temp =  xml2js.parseStringSync(xmlData.content);
console.log(temp.city);

and it comes back as undefined. New to using JSON, so still unsure of what to do:)


#12

console the json object and actually look at it. The structure is not what you’d expect. The children always start with an array i think.


#13

It comes back as:

Object {current: Object}
   current: Objectcity: Array[1]
     clouds: Array[1]
     humidity: Array[1]
     lastupdate: Array[1]
     precipitation: Array[1]
     pressure: Array[1]

etc...

I am trying to get the data from ‘city’…


#14

Any ideas from any one?


#15

As @sikanx says, the structure is not what you may expect. I don’t think there’s enough information in what you have shown for the object. Instead of showing us the console.log of temp can you show us the console.log of xmlData.content (the raw JSON)?


#16

The raw XML is:

<current><city id="2158177" name="Melbourne"><coord lon="144.96" lat="-37.81"></coord><country>AU</country><sun rise="2015-11-24T18:53:52" set=
"2015-11-25T09:20:59"></sun></city><temperature value="286.15" min="286.15" max="286.15" unit="kelvin"></temperature><humidity value="43" unit="%"></humidity><pressure value="1008" uni
t="hPa"></pressure><wind><speed value="9.8" name="Fresh Breeze"></speed><gusts value="15.4"></gusts><direction value="250" code="WSW" name="West-southwest"></direction></wind><clouds v
alue="75" name="broken clouds"></clouds><visibility value="10000"></visibility><precipitation mode="no"></precipitation><weather number="803" value="broken clouds" icon="04n"></weather
><lastupdate value="2015-11-25T22:43:00"></lastupdate></current>

And I am trying to get the data from the “value=“broken clouds”” part…

It’s not JSON yet though! I am getting XML data from the weather service, then parsing it to JSON, then I want to get the “broken clouds” part.
Or should I just get it right from the raw XML?


#17

You’re absolutely right about it being in XML :smile:. However, it’s not parsed to JSON, but to a JS object. So, I took your XML and ran it through xml2js and then converted it into a pretty JSON, so the structure can be seen (remember it’s not in JSON following xml2js, but this makes it easier to understand):

{
  "current": {
    "city": [{
      "$": {
        "id": "2158177",
        "name": "Melbourne"
      },
      "coord": [{
        "$": {
          "lon": "144.96",
          "lat": "-37.81"
        }
      }],
      "country": ["AU"],
      "sun": [{
        "$": {
          "rise": "2015-11-24T18:53:52",
          "set": "2015-11-25T09:20:59"
        }
      }]
    }],
    "temperature": [{
      "$": {
        "value": "286.15",
        "min": "286.15",
        "max": "286.15",
        "unit": "kelvin"
      }
    }],
    "humidity": [{
      "$": {
        "value": "43",
        "unit": "%"
      }
    }],
    "pressure": [{
      "$": {
        "value": "1008",
        "unit": "hPa"
      }
    }],
    "wind": [{
      "speed": [{
        "$": {
          "value": "9.8",
          "name": "Fresh Breeze"
        }
      }],
      "gusts": [{
        "$": {
          "value": "15.4"
        }
      }],
      "direction": [{
        "$": {
          "value": "250",
          "code": "WSW",
          "name": "West-southwest"
        }
      }]
    }],
    "clouds": [{
      "$": {
        "value": "75",
        "name": "broken clouds"
      }
    }],
    "visibility": [{
      "$": {
        "value": "10000"
      }
    }],
    "precipitation": [{
      "$": {
        "mode": "no"
      }
    }],
    "weather": [{
      "$": {
        "number": "803",
        "value": "broken clouds",
        "icon": "04n"
      }
    }],
    "lastupdate": [{
      "$": {
        "value": "2015-11-25T22:43:00"
      }
    }]
  }
}

So, to get to your “broken clouds”, you need to traverse the object (as returned into temp by xml2js):

temp.current.clouds[0]['$'].name   // "broken clouds"

clouds is not part of the city object (which seems odd), but agrees with the XML:

<current>
  <city id="2158177" name="Melbourne">
    <coord lon="144.96" lat="-37.81"></coord>
    <country>AU</country>
    <sun rise="2015-11-24T18:53:52" set="2015-11-25T09:20:59"></sun>
  </city>
  <temperature value="286.15" min="286.15" max="286.15" unit="kelvin"></temperature>
  <humidity value="43" unit="%"></humidity>
  <pressure value="1008" unit="hPa"></pressure>
  <wind>
    <speed value="9.8" name="Fresh Breeze"></speed>
    <gusts value="15.4"></gusts>
    <direction value="250" code="WSW" name="West-southwest"></    direction>
  </wind>
  <clouds value="75" name="broken clouds"></clouds>
  <visibility value="10000"></visibility>
  <precipitation mode="no"></precipitation>
  <weather number="803" value="broken clouds" icon="04n"></weather>
  <lastupdate value="2015-11-25T22:43:00"></lastupdate>
</current>

HTH


#18

And for anyone wanting to do this and use openweather maps, it returns temperatures in degrees kelvin unless you put:

&units=metric

Thanks heaps everyone!