Узел выражает несколько запросов в одном маршруте, которые зависят друг от друга - PullRequest
0 голосов
/ 07 марта 2019

Я как раз собираюсь познакомиться с node, express и программированием в целом, но это более сложная проблема, которую я пытаюсь решить. Пожалуйста, если вы можете предоставить лучшую практику в этом сценарии.

Я пытаюсь выполнить два запроса к моей базе данных, где первый зависит от результата первого. Q1. Вернуть список идентификаторов. Q2. Вернуть идентификатор и координаты для каждого из идентификаторов. Я хочу ответить с помощью объекта json, который выглядит примерно так

[
  { id: 451, coords: 'POINT(12.5574 43.8351)' },
  { id: 56, coords: 'POINT(13.5574 44.8351)' }
]

В настоящее время я не могу заставить его работать, я знаю, что, возможно, есть несколько проблем с моим примером кода, но я довольно сильно застрял. Может быть, я обдумываю это и усложняю, или это плохая практика в целом. Как я могу выполнить несколько запросов, когда второй использует выходные данные первого, а затем построить правильный объект для ответа. Любые указатели будут высоко оценены.

router.get('/asset/:id', (req, res) => {
  let latLngOfAssets = []
  // get associated assets
  function getConnectionsById() {
    queries.getConnectionsById(req.params.id)  // return list of objects
    .then(data => {
      if (data) {
        data.forEach(function(element) {
          getLatLngofAsset(element.til_poi_id)  // for each id in list call function to get coordinate
        });
      } else {
        throw new Error('No data returned');
      }
      console.log(latLngOfAssets) // What I want to respond with res.json(latlngofassets)
    })
  }

  function getLatLngofAsset(id) {
    queries.getPoilatlng(id)  // Return geometry as text for asset with id
    .then(data =>{
      let newassetobj = {}
      if (data) {
        newassetobj["id"] = data.rows[0].id
        newassetobj["coords"] = data.rows[0].st_astext
        //console.log(newassetobj)  // structure of each object { id: 451, coords: 'POINT(12.5574 43.8351)' }
        latLngOfAssets.push(newassetobj) // making list of objects i want to respond with
      } else {
        throw new Error('Did not get any poi');
      }
    })    
  }

  getConnectionsById()

  .catch(err => { // {message: "Cannot read property 'then' of undefined", error: {…}}
    console.error('Something went wrong', err);
  });
});

1 Ответ

0 голосов
/ 07 марта 2019

Вы проделали хорошую работу, разделив два отдельных раздела вашего кода на отдельные функции - вам не хватает возможности связать их вместе.Эта часть вашего кода не выполняет то, что, я думаю, вы пытаетесь выполнить:

data.forEach(function(element) {
  getLatLngofAsset(element.til_poi_id)
});

Поскольку getLatLngofAsset() основано на Promise *, вам нужно использовать его как Promise.Сначала вам нужно заставить getLatLngofAsset вернуть созданную им цепочку Promise.Тогда это может быть await -ed внутри getConnectionsById с использованием функции async:

 function getConnectionsById() {
    queries.getConnectionsById(req.params.id)
    .then(data => {
      if (data) {
        data.forEach(async function(element) { // <-- note the async keyword here
          await getLatLngofAsset(element.til_poi_id)
        });
      } else {
        throw new Error('No data returned');
      }
      console.log(latLngOfAssets) // What I want to respond with res.json(latlngofassets)
    })
  }

Это начало - есть еще пара вещей, которые мы можем решить, как только вы поймете связь междуобъявленные вами функции и обещания, которые они создают и возвращают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...