2017-01-03 2 views
0

J'ai créé un crochet avant sauvegarde dans mon application api de loopback. Mon modèle d'emplacement a une adresse et un géopoint latlngLoopback Geopoint Hook pas de changement persistant

"properties": { 
    "name": { 
     "type": "string" 
    }, 
    "address": { 
     "type": "string" 
    }, 
    "latlng": { 
     "type": "geopoint" 
    } 
    }, 

Dans mon common\models\location.js je le code suivant:

var https = require('https'); 
var loopback = require('loopback'); 
module.exports = function(Location) { 
    Location.observe('before save', function(ctx, next) { 
    let path = `/maps/api/geocode/json?address=${ctx.instance['address']}&key=AIzaSyCWk3ePB8idTw74LyhR8tLSCmVgbZDKiIQ` 
    console.log(path); 
    https.get({ 
     hostname: 'maps.googleapis.com', 
     path: encodeURI(path) 
    }, (res) => { 
     var body = []; 
     res.on('data', (d) => { 
     body.push(d) 
     }) 
     res.on('end',() =>{ 
     body = JSON.parse(Buffer.concat(body).toString()); 
     let latlng = new loopback.GeoPoint({ 
      lat: body['results'][0]['geometry']['location']['lat'], 
      lng: body['results'][0]['geometry']['location']['lng'] 
     }) 
     console.log(latlng) 
     if (ctx.instance) { 
      ctx.instance.latlng = latlng; 
     } else { 
      ctx.data.latlng = latlng; 
     } 
     }) 
    }) 
    next(); 
    }) 
}; 

Ce que je me attends à ce code à faire est de faire une http (s) demande à google maps, renvoie la latitude et la longitude de l'adresse, prédisera naïvement la première entrée correcte et conservera cette donnée dans mon modèle dans la propriété latlng. Je restituent correctement à la console la latitude et la longitude attendue comme un objet GeoPoint:

GeoPoint { lat: 42.3675294, lng: -71.18696609999999 } 

Comment puis-je mettre à jour mon modèle avec cette information? J'ai essayé d'enlever le if (ctx.instance) conditionnel sans différence. J'ai essayé d'utiliser une autre notation d'objet:

ctx.instance['latlng']=latlng 

Aucune erreur n'a été consignée. Je persiste avec MongoDB, mais le problème est le même en utilisant db en mémoire. Le code supplémentaire situé sur Github.com/andygauge/api.socialconnect

Répondre

1

Le problème ici est le placement de next(). En raison de la nature asynchrone de nodejs, next() a été appelée avant que la requête http ne soit terminée et traitée. Les modifications apportées au modèle se produisent après la validation du workflow.

La solution ressemble à ceci:

module.exports = function(Location) { 
    Location.observe('before save', function(ctx, next) { 
    let path = `/maps/api/geocode/json?address=${ctx.instance['address']}&key=AIzaSyCWk3ePB8idTw74LyhR8tLSCmVgbZDKiIQ` 
    console.log(path); 
    https.get({ 
     hostname: 'maps.googleapis.com', 
     path: encodeURI(path) 
    }, (res) => { 
     var body = []; 
     res.on('data', (d) => { 
     body.push(d) 
     }) 
     res.on('end',() =>{ 
     body = JSON.parse(Buffer.concat(body).toString()); 
     let latlng = new loopback.GeoPoint({ 
      lat: body['results'][0]['geometry']['location']['lat'], 
      lng: body['results'][0]['geometry']['location']['lng'] 
     }) 
     console.log(latlng) 
     if (ctx.instance) { 
      ctx.instance.latlng = latlng; 
     } else { 
      ctx.data.latlng = latlng; 
     } 
     next(); 
     }) 
    }) 
    }) 
}; 

Merci pour la vue.