Need help digesting JSON blob returned using express-handlebars node.js

601 views Asked by At

I'm getting started with node.js and am working through a tutorial that pings the Accuweather API and returns a JSON blob of data.

I've ALMOST got it ... but the display piece is what's holding me back:

index.js

const express = require('express')
const rp = require('request-promise')
const exphbs = require('express-handlebars')
const path = require('path')
const app = express()

app.engine('.hbs', exphbs({
  defaultLayout: 'main',
  extname: '.hbs',
  layoutsDir: path.join(__dirname, 'views/layouts')
}))
app.set('view engine', '.hbs')
app.set('views', path.join(__dirname, 'views'))

app.get('/:city', (req, res) => {
  rp({
      uri: 'http://apidev.accuweather.com/locations/v1/search',
      qs: {
    q: req.params.city,
    apiKey: 'hoArfRosT1215'
      // Use your accuweather API key here
  },
  json: true
})
.then((data) => {
  console.log(data)
  res.render('home', data)
})
.catch((err) => {
  console.log(err)
  res.render('error')
})
})

app.listen(3000)

home.hbs

  <h2>Success!</h2>
  <h2>{{data}}</h2>`

error.hbs

 <h2>Error<h2>

home.hbs

<html>
  <head>
    <title>Express handlebars</title>
  </head>
  <body>
    {{{body}}}
  </body>
</html>

I've Googled and haven't really found a great solution. I've looked into handlebars helped functions ... but didn't really come up with anything.

How would I start to display some of the 'data' chunk coming back from the Accuweather API?

FYI here's there JSON blog that comes back I got from console.logging it

[ { Version: 1,
    Key: '2156696',
    Type: 'City',
    Rank: 385,
    LocalizedName: 'Providence Forge',
    EnglishName: 'Providence Forge',
    PrimaryPostalCode: '19468',
    Region: 
     { ID: 'NAM',
       LocalizedName: 'North America',
       EnglishName: 'North America' },
    Country: 
     { ID: 'US',
       LocalizedName: 'United States',
       EnglishName: 'United States' },
    AdministrativeArea: 
     { ID: 'PA',
       LocalizedName: 'Pennsylvania',
       EnglishName: 'Pennsylvania',
       Level: 1,
       LocalizedType: 'State',
       EnglishType: 'State',
       CountryID: 'US' },
    TimeZone: 
     { Code: 'EST',
       Name: 'America/New_York',
       GmtOffset: -5,
       IsDaylightSaving: false,
       NextOffsetChange: '2017-03-12T07:00:00Z' },
    GeoPosition: { Latitude: 40.18, Longitude: -75.523, Elevation: [Object] },
    IsAlias: false,
    SupplementalAdminAreas: [ [Object] ],
    DataSets: [ 'Alerts', 'ForecastConfidence', 'MinuteCast' ] },
  { Version: 1,
    Key: '2172276',
    Type: 'City',
    Rank: 385,
    LocalizedName: 'Providence Forge',
    EnglishName: 'Providence Forge',
    PrimaryPostalCode: '23140',
    Region: 
     { ID: 'NAM',
       LocalizedName: 'North America',
       EnglishName: 'North America' },
    Country: 
     { ID: 'US',
       LocalizedName: 'United States',
       EnglishName: 'United States' },
    AdministrativeArea: 
     { ID: 'VA',
       LocalizedName: 'Virginia',
       EnglishName: 'Virginia',
       Level: 1,
       LocalizedType: 'State',
       EnglishType: 'State',
       CountryID: 'US' },
    TimeZone: 
     { Code: 'EST',
       Name: 'America/New_York',
       GmtOffset: -5,
       IsDaylightSaving: false,
       NextOffsetChange: '2017-03-12T07:00:00Z' },
    GeoPosition: { Latitude: 37.442, Longitude: -77.044, Elevation: [Object] },
    IsAlias: false,
    SupplementalAdminAreas: [ [Object] ],
    DataSets: [ 'Alerts', 'ForecastConfidence', 'MinuteCast' ] } ]
2

There are 2 answers

0
leroydev On

The way to pass variables to views is as attributes of the second object parameter, so change this:

res.render('home', data);

To this:

res.render('home', {data: data});

Source.

As for displaying the data, you can iterate over the JSON array and display it in home.hbs like this:

<h2>Success!</h2>
<ul>
  {{#each data}}
    <li>
      Name: {{this.EnglishName}}<br>
      Region: {{this.Region.EnglishName}}
    </li>
  {{/each}}
</ul>

More info about the each helper can be found on this page.

3
Eliezer Wohl On

Okay, so you have as:

 res.render('home', data)

I believe it should be:

res.render("home", {data:data})

as for your html

  {{#each data}}
   <div>
      Name: {{this.LocalizedName}}
      Rank: {{this.Rank}}
   </div>
  {{/each}}