0

I am querying AMPS SOW using javascript API. My functions look like this:

sow_query = async(topic, filter, options) => {
await this.connection
await this.client.sow(this.onMessage, topic, filter, options)
return this.message
}

onMessage = (message)=>{
this.message.push(message.data)
}

//Calling functions
const getData = async(date) =>{
let data = await getAmpsData(date)
}

async getAmpsData(date){
const filter = "some filter"
const data = await ampsClient.sow_query(topic, filter)
data.forEach((element) => console.log(element))
}

It looks like my call to ampsClient.sow_query doesnt wait for the callback to finish so returns an empty list. Therefore, I cannot loop through the data in my calling function getAmpsData. I know it has to do with async/await because if I simply do console.log(data) in getAmpsData i can see the data (perhaps after 2 seconds) when the promise is resolved. Is there anyway i can get this working?

santosh
  • 57
  • 7
  • What is `ampsClient` anyway? Is there documentation for it? – David Knipe Apr 04 '21 at 11:28
  • `await this.connection` looks weird, and so does the `await this.client.sow` call that passes an `onMessage` callback. Can you please post the full class and documentation on the `connection` and `client` objects? – Bergi Apr 04 '21 at 12:32

2 Answers2

0

If I understand you correctly, data in getAmpsData is an array as expected, but data in getData is undefined. It's not an async/await problem, you just forgot to add return data; to getAmpsData.

David Knipe
  • 3,417
  • 1
  • 19
  • 19
  • Thanks for looking into this. Dont think it has to do with return. The issue is i cant even access the data in getAmpsData function. When I try to loop through, it doesnt work. – santosh Apr 04 '21 at 11:18
0

I not sure about what package you are using. But, maybe, it using a callback function to get the result of .sow function - message.data.

With your logic, onMessage function will be called after data.forEach done, you can try adding a console.log line to onMessage function.

Maybe, the package has an important reason to do that. But, to fix this issue, you can wrap .sow function into a promise.

sow_query = async (topic, filter, options) => {
  await this.connection // ???
  return new Promise((resolve) => { // wrap in a promise
    this.client.sow( // no need to wait .sow
      (message) => {
        resolve(message.data); // just resolve when we get the message's data
      },
      topic, filter, options)
  });
}

//Calling functions
const getData = async (date) => {
  let data = await getAmpsData(date)
}

async getAmpsData(date) {
  const filter = "some filter"
  const data = await ampsClient.sow_query(topic, filter)
  data.forEach((element) => console.log(element))
}
hoangdv
  • 15,138
  • 4
  • 27
  • 48
  • 1
    I think your hunch is correct, but [never pass an `async function` as the executor to `new Promise`](https://stackoverflow.com/q/43036229/1048572)! – Bergi Apr 04 '21 at 12:34
  • @Bergi Ahh, thanks for reminding me! Maybe I need to wrap all logic inside Promise constructor to a `try/catch` block, and throw an error via `reject` param. – hoangdv Apr 04 '21 at 12:42