12

I have written a code to return some data from asynchronous call using promise. While I try to execute I get "Syntax Error await is only valid in async function" and also I get Cannot proxy application requests...Error: connect ECONNREFUSED.

I'm unsure why I get these errors

I have tried using async before the function calls, but it didn't work

var http = require('https');
var httpGet = function(url) {
  return new Promise (function(resolve, reject) {
    http.get(url,function(res) {
      res.setEncoding('utf8');
      var body = ''; 
      res.on('data', function(chunk){ 
        body += chunk;
        console.log("The body is "+ body);
      });
      res.on('end',function(){resolve(body);});
    }).on('error', reject);
  });
};

var body = await httpGet('link');
$.response.setBody(body);

I would want variable body to have the data returned from the httpGet function. Right now I'm getting the above mentioned errors. But without using await, I get the value of body as '{}'.

Please help

Arun Elangovan
  • 237
  • 1
  • 3
  • 16
  • Does this answer your question? [await is only valid in async function](https://stackoverflow.com/questions/49432579/await-is-only-valid-in-async-function) – Serge Stroobandt Mar 25 '21 at 07:13

2 Answers2

24

await can only be called in a function marked as async. so, you can make an async IIFE and call the httpGet from there.

(async function(){
    var body = await httpGet('link');
    $.response.setBody(body);
})()

Basically when you use one asynchronous operation, you need to make the entire flow asynchronous as well. So the async keyword kindof uses ES6 generator function and makes it return a promise.

You can check this out if you have confusion.

Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35
  • 1
    Thanks it works. But I'm not able to store the data in a global variable. Below is what i tried. var result; (async function(){ result = await httpGet('link'); $.response.setBody(result); })() console.log("The result is "+result); – Arun Elangovan Jun 20 '19 at 12:54
  • I get the result as undefined. How to retrieve the data and store in a global variable? Here i'm not able to set the body too. It returns null value – Arun Elangovan Jun 20 '19 at 12:58
  • You will get the result undefined because the `console.log` will run just after initating the `async` function. You cannot use sync and async operations at the same time. – Aritra Chakraborty Jun 20 '19 at 13:59
  • Do you have any idea on how to solve this issue? I'm stuck with this – Arun Elangovan Jun 20 '19 at 14:05
  • It depends on what you want to do with the data. If you want to show it in ui then make a placeholder page, and after the data is there change the page. Or if you want to use a route to return it as an api response you can do that also. – Aritra Chakraborty Jun 20 '19 at 14:07
  • I would like to store the data in some global variable and use that for other operations in the same file. Is it possible? – Arun Elangovan Jun 20 '19 at 14:11
  • ha obviously but you need to do the other operations AFTER the httpGet operation. That means you can do any operations after the `await` in the `async` function. – Aritra Chakraborty Jun 20 '19 at 14:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/195285/discussion-between-arun-elangovan-and-aritra-chakraborty). – Arun Elangovan Jun 20 '19 at 14:27
1

This is what worked for me.

I initially had:

exports.doSomething = functions.database.ref('/posts/{postId}').onCreate((snapshot, context) => {

    // ... 

    const [response] = await tasksClient.createTask({ parent: queuePath, task });
});

But I added the word async here (before the open parentheses to snapshot) and then the error went away

       // here
.onCreate(async (snapshot, context) => {

So now the code is

exports.doSomething = functions.database.ref('/posts/{postId}').onCreate(async (snapshot, context) => {

    // ... 

    const [response] = await tasksClient.createTask({ parent: queuePath, task });
});
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256