Lambda devolviendo 200 con un objeto vacío, sin esperar a que le devuelvan la llamada para disparar

votos
25

Estoy golpeando el api de google calendar, y tengo una configuración lambda en un asny try catch. He tratado de añadir espera a cada función, he tratado de mover el retorno a después del if(err) pero eso me da un 500. Lo que necesito hacer es pasar los datos de la matriz de la función de la API de Google Calendar al mensaje para que pueda tenerlo en mi frontal. Aquí está la lambda hasta ahora. Cualquier ayuda sería muy apreciada. Gracias


const { google } = require(googleapis)
const { OAuth2 } = google.auth
const faunadb = require(faunadb) /* Import faunaDB sdk */

// Docs on event and context https://www.netlify.com/docs/functions/#the-handler-method
exports.handler = async (event, context) => {
  try {
    const OAuth2Client = new OAuth2(
      FDSAF,
      FDSAF
    )

    // Connect to the database
    const q = faunadb.query
    const client = new faunadb.Client({
      secret: FDSAFA,
    })

    let refreshToken

    await client
      .query(q.Get(q.Ref(q.Collection(AuthUrl), fdsa)))
      .then(ret => (refreshToken = ret.data.title.refresh_token))

    console.log(refreshToken)

    OAuth2Client.setCredentials({
      refresh_token: refreshToken,
    })

    // Create a new calender instance.
    const calendar = google.calendar({ version: v3, auth: OAuth2Client })



    let ok
    function listEvents(callback) {
      let array = []

      calendar.events.list(
        {
          calendarId: primary,
          // timeMin: new Date().toISOString(),
          maxResults: 100000,
          singleEvents: true,
          orderBy: startTime,
        },
        (err, res) => {
          if (err) return console.log(The API returned an error:  + err)

          var date = new Date()
          var firstDay = new Date(date.getFullYear(), date.getMonth(), 1)
          var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0)

          //console.log(res.data.items)
          const events = res.data.items
          if (events.length) {
            //   console.log(Upcoming 10 events:)
            events.map((event, i) => {
              const start = new Date(event.start.dateTime || event.start.date)
              const end = new Date(event.end.dateTime || event.end.date)

              if (start >= firstDay && end <= lastDay) {
                console.log(start, end, event.summary)
                //ok = test
                array.push(start)
                callback(array)
              }

              //     const start = event.start.dateTime || event.start.date
              //     console.log(`${start} - ${event.summary}`)
            })
          } else {
            console.log(No upcoming events found.)
          }
        }
      )
    }

    let array

    listEvents(function (eventList) {
      array = eventList
    })



    return {
      statusCode: 200,
      body: JSON.stringify({ message: array }),
      // // more keys you can return:
      // headers: { headerName: headerValue, ... },
      // isBase64Encoded: true,
    }
  } catch (err) {
    return { statusCode: 500, body: err.toString() }
  }
}

Esta es la recogida que hago en la parte delantera y devuelve un objeto vacío

const IndexPage = () => {
  fetch(/functions/list-calendar)
    .then(response => response.json())
    .then(response => {
      console.log(response)
    })
Publicado el 17/05/2020 a las 20:06
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
0

Me parece que estás devolviendo tu respuesta antes de que la llamada se haya ejecutado. Si no estás familiarizado con asyncy await, deberías leer esta documentación. Básicamente, debes esperar a que se produzca la devolución de llamada antes de volver, y puedes hacerlo utilizando las funciones de devolución de llamada, y luego las funciones de cadenas o de sincronización

También noté en tu código que llamas a la llamada cada vez que haces un push into array. Creo que es más sencillo introducir todos tus objetos arrayy luego llamar a la matriz

En lugar de hacer un empuje en el mapa (lo cual es confuso), esto devuelve un nuevo arreglo de event.start.dateTime y porque si (start >= firstDay && end <= lastDay)es falso, agrega un a nullal arreglo, así .filter(x => Boolean(x));que los filtra para obtener un arreglo de fechas-horas.

let array = events.map((event, i) => {
    const start = new Date(event.start.dateTime || event.start.date)
    const end = new Date(event.end.dateTime || event.end.date)

    if (start >= firstDay && end <= lastDay) {
      return start;
    else
      return null;

      //     const start = event.start.dateTime || event.start.date
      //     console.log(`${start} - ${event.summary}`)
    })
    .filter(x => Boolean(x));

Versión simple

Podrías mover tu regreso a la llamada.

listEvents(function (eventList) {
  array = eventList;

  return {
    statusCode: 200,
    body: JSON.stringify({ message: array }),
    // // more keys you can return:
    // headers: { "headerName": "headerValue", ... },
    // isBase64Encoded: true,
  }
});

Versión de la promesa

Mi nodo está un poco oxidado pero podrías cambiar tu método para devolver una promesa.

function listEvents(callback) {
  return new Promise((resolve, reject) => {


    calendar.events.list(
    {
      calendarId: "primary",
      // timeMin: new Date().toISOString(),
      maxResults: 100000,
      singleEvents: true,
      orderBy: "startTime",
    },
    (err, res) => {
      if (err) reject("The API returned an error: " + err));

      var date = new Date()
      var firstDay = new Date(date.getFullYear(), date.getMonth(), 1)
      var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0)

      //console.log(res.data.items)
      const events = res.data.items
      if (events.length) {
        //   console.log("Upcoming 10 events:")
        let array = events.map((event, i) => {
          const start = new Date(event.start.dateTime || event.start.date)
          const end = new Date(event.end.dateTime || event.end.date)

          if (start >= firstDay && end <= lastDay) {
            return start;
          else
            return null;

          //     const start = event.start.dateTime || event.start.date
          //     console.log(`${start} - ${event.summary}`)
        }).filter(x => Boolean(x));

        resolve(array);
      } else {
        resolve([]);
      }
    })
  });
}

y luego, como ya estás usando async,

id="pre-3"
Respondida el 23/05/2020 a las 15:33
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more