2016-02-22 18 views
6

Sto usando Syncano come un baas, dove sto provando a chiamare un'API esterna per ricevere un array JSON. Questo JSON deve essere analizzato e successivamente memorizzato in syncano. Prima di ciò ho bisogno di ricevere l'oggetto di riferimento dal DB per collegarlo al nuovo oggetto del team.Syncano Codebox - Chiama API - parse JSON - ottieni riferimento - Salva nuovi oggetti

Ricevo correttamente l'oggetto di riferimento della squadra (json) &. Ma non riesco a ottenere i nuovi dati memorizzati, poiché solo 12-14 squadre (devono essere 18) vengono salvate.

Ho provato questo & con promesse ma non ha funzionato. Qualcuno un buon consiglio come riscrivere il codice per memorizzare tutti i dati? Grazie - ecco quello che ho finora ...

//TODO: get from ARGS when executing this codebox 
var teamKey = 394; 
var requestURL = 'http://api.football-data.org/v1/soccerseasons/' + teamKey + "/teams"; 

var request = require("request"); 
var Syncano = require('syncano'); 
var Promise = require('bluebird'); 
var account = new Syncano({ 
    accountKey: "abc" 
}); 
var promises = []; 

//from: http://docs.syncano.io/v1.0/docs/data-objects-filtering 
//"_eq" means equals to 
var filter = { 
    "query": { 
    "apikey": { 
     "_eq": apiKey 
    } 
    } 
}; 

request({ 
    headers: { 
    'X-Auth-Token': 'abc' 
    }, 
    url: requestURL, 
    'Content-Type': 'application/json;charset=utf-8;', 
    method: 'GET', 
}, function(error, response, body) { 
    if (error) { 
    console.log(error); 
    } else { 
    var json = JSON.parse(body); 
    var teamArray = json.teams; 
    var newObject; 

    account.instance('instance').class('competition').dataobject().list(filter) 
    .then(function(compRes) { 

     var competitionID = compRes.objects[0].id; 
     for (var i = 0; i < teamArray.length; i++) { 
      newObject = { 
      "name": teamArray[i].name, 
      "nameshort": teamArray[i].code, 
      "logo": teamArray[i].crestUrl, 
      "competition": competitionID 
      }; 

      (account.instance('instance').class('teams').dataobject().add(newObject).then(function(res) { 
       console.log(res); 
      }).catch(function(err) { 
       console.log("Error eq: " + err); 
      }) 
     ); 
     } 
     }).catch(function(err) { 
     console.log(err); 
     }); 
    } 
}); 
+0

avete il tempo di esecuzione della versione corrente di codice? –

+0

Sì, è 2002 ms @KellyJAndrews – Burkart

+0

Il tuo codice sembra fondamentalmente ok - penso che potrebbe essere il 15 req/secondo che stai incontrando qui. –

risposta

4

Il problema potrebbe essere si stanno completando il processo di richiesta prima che tutte le chiamate salvataggio sono fatti, si potrebbe provare Promise.all():

account.instance('instance').class('competition').dataobject().list(filter) 
    .then(function(compRes) { 

     var competitionID = compRes.objects[0].id, promises=[]; 
     for (var i = 0; i < teamArray.length; i++) { 
      newObject = { 
      "name": teamArray[i].name, 
      "nameshort": teamArray[i].code, 
      "logo": teamArray[i].crestUrl, 
      "competition": competitionID 
      }; 
      promises.push(account.instance('instance').class('teams').dataobject().add(newObject).then(function(res) { 
       console.log(res); 
      }).catch(function(err) { 
       console.log("Error eq: " + err); 
      }) 
     ); 
     } 
     return Promise.all(promises); 
     }).catch(function(err) { 
     console.log(err); 
     }); 

se troppe chiamate parallele in un momento è il problema allora concatenare una chiamata dopo l'altro:

account.instance('instance').class('competition').dataobject().list(filter) 
    .then(function(compRes) { 

     var competitionID = compRes.objects[0].id, promise = Promise.resolve(); 
     function chainToPromise(promise, teamObj, waitTime){ 
      waitTime = waitTime || 500; 
      return promise.then(function(){ 
      return new Promise(function(resolve, reject){ 
       setTimeout(resolve, waitTime); 
      }); 
      }).then(function(){ 
      return account.instance('instance').class('teams').dataobject().add(teamObj); 
      }).then(function(res) { 
      console.log(res); 
      }).catch(function(err) { 
      console.log("Error eq: " + err); 
      }); 
     } 
     for (var i = 0; i < teamArray.length; i++) { 
      newObject = { 
      "name": teamArray[i].name, 
      "nameshort": teamArray[i].code, 
      "logo": teamArray[i].crestUrl, 
      "competition": competitionID 
      }; 
      promise = chainToPromise(promise, newObject); 
     } 
     return promise; 
     }).catch(function(err) { 
     console.log(err); 
     }); 
+0

Per il primo ricevo: "[TypeError: Can not read property 'push' of undefined]" - al momento non riesco a capire da dove provenga. Per il secondo, una squadra viene memorizzata più volte, sembra che il ciclo venga eseguito 18 volte e successivamente il metodo add() venga eseguito solo per 1 oggetto più volte. Tuttavia, ricevo ancora il messaggio "Richiesta è stata limitata". – Burkart

+0

@Burkart il mio codice errato e aggiornato, il primo non ho inizializzato 'promises', il secondo codice ha avuto un problema di chiusura, inoltre ho aggiunto un intervallo di 500ms tra due risparmi nel secondo metodo ... – mido

+0

Grazie mille! Ha funzionato! – Burkart