0

I am quite newbie with node.js. What i am trying to achieve is the following:

  1. Connect to my postgresql database and get info of three places (id, coordinates). For each place obtained i need:
  2. Call a weather api and get the info of that spot using the coordinates obtained in the previous step.
  3. Insert the returned json in the database. I get 8 hourly objects, with the weather info every 3 hours (0,3,6,9,12,15,18,21). I need to iterate through this objects and then store them in 8 records in the database.

I have written the following code so far:

function insert_forecast_spot(id, body, client) {
  var date = body.data.weather[0].date;
  var callbacks = 0;

    for (var i=0; i < 8; i++) {

    var hourly = body.data.weather[0].hourly[i];

    client.query('INSERT into parte (id, date, time) VALUES($1, $2, $3)',
                      [id, date, hourly.time], 
                      function(err, result) {
                             if (err) {
                                console.log(err); 
                              } else {
                                console.log('row inserted: ' + id + ' iteration ' + i);
                                callbacks++;
                                if (callbacks === 8) {
                                  console.log('All callbacks done!from id '+id);
                                }
                              }   
                            });
    } //for
  } // function


app.get('/getapi', function(req, res, next){  
//------------ BBDD CONNECTION----------------

  pg.connect(conString, function(err, client, done) {
    if(err) {
      // example how can you handle errors
      console.error('could not connect to postgres',err);
      return next(new Error('Database error'));
    }
    client.query('SELECT * from places where id>3274 and id<3278', function(err, result) {
      if(err) {
        console.error('error running query',err);
        done();
        return next(new Error('Database error'));
      }
      done();
      var first_callback = 0;
      for (var y=0;  y<result.rows.length; y++) {
          console.log('y'+y);
          var coords = JSON.parse(result.rows[y].json).coordinates;
          var id = result.rows[y].id;
          var input = {
            query: coords[1] + ',' + coords[0] ,
            format: 'JSON',
            fx: ''
          };

          var url = _PremiumApiBaseURL + "marine.ashx?q=" + input.query + "&format=" + input.format + "&fx=" + input.fx + "&key=" + _PremiumApiKey;  

          request(url,function (err, resp, body){

              body = JSON.parse(body);
              if (!err && resp.statusCode == 200) {

                  insert_forecast_spot(id,body, client);
              }
              else { 
                 console.error(err);
                 done();    // done(); is rough equivalent of client.end();  
              }
            });

      first_callback++;
      if (first_callback === result.rows.length-1) {
        console.log('All global callbacks done!');
        done();    // done(); is rough equivalent of client.end();
        res.send("done");
      }} 
    }); // SELECT 
  }); // CONNECT
}); // app.get

What it does is try to insert the id=3277 spot's forecast three times!

The console logs is as follows:

y0
y1
All global callbacks done!
GET /getapi 200 40ms - 4b
y2
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
row inserted: 3277 iteration 8
All callbacks done!from id 3277
{ [error: duplicate key value violates unique constraint "parte_pkey"]
  name: 'error',
  length: 178,
  severity: 'ERROR',
  code: '23505',
  detail: 'Key (id, date, "time")=(3277, 2013-11-22, 0) already exists.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  file: 'nbtinsert.c',
  line: '397',
  routine: '_bt_check_unique' }

this final error repeats 16 times as it tries to insert again the 8 records of the place two times.

Joe Doyle
  • 6,363
  • 3
  • 42
  • 45
Egidi
  • 1,736
  • 8
  • 43
  • 69

0 Answers0