skip to Main Content

I am a JavaScript beginner. have an async function, that has an await method in it, problem is that after obtaining the return value from that async function when I am passing it as a parameter to another function and iterating over it using a forEach it says data.ForEach is not a function

Here is my code

async function javed(){
  var map1 = new Map();

  map1 = await createMap();


  return map1;


 }

 function createMap(){

  var map2 = new Map();
  map2.set('11', true);
  map2.set('22', true);
  map2.set('33', false);
  map2.set('44', true);

  return map2;


 }

  let x = this.javed();
  this.Dome(x);



  function Dome(res){

    res.forEach(x =>{
      console.log('inside dome', x);

    })

  }

This shows the following error


Uncaught TypeError: res.forEach is not a function
at Dome (myfile.js:83:9)

Also I am not getting during the iteration how would I get the individual key and value if I want to manipulate or just console them?

3

Answers


  1. Your problem is, that all async functions return a Promise.
    So you’re not calling forEach() on a Map as you would expect, but instead on a Promise which does not have that function.
    Use let x = await javed(); in order to resolve that promise and get back a Map.

    Generally I would advise you to use the this keyword sparingly in JS, you don’t need it at all in your example and it can often be something other that what you expect. Also, try not to use var anymore. const and let are much more isolated from external scripts and their scoping is easier to understand.

    Here’s a working example with the added await. If top-level await is not supported, you can wrap the behavior in a new async function as I have done here:

    async function javed() {
      var map1 = new Map();
      // createMap is not async, so no reason to await it
      map1 = await createMap();
      return map1;
    
    
    }
    
    function createMap() {
      var map2 = new Map();
      map2.set('11', true);
      map2.set('22', true);
      map2.set('33', false);
      map2.set('44', true);
      return map2;
    }
    
    async function doEverything() {
    // you need to await javed
    let x = await this.javed();
    this.Dome(x);
    }
    // call the async function
    doEverything();
    
    
    
    function Dome(res) {
    
      res.forEach(x => {
        console.log('inside dome', x);
    
      })
    
    }

    EDIT: Yes, if you need a promise to resolve, you need to await it, requiring an async function.
    The "old" way of using Promises (which await is actually just syntactic sugar for) does not require you to make the function async, but executes non-linearly. Here’s an example:

    // I've cleaned up the code a bit, removing this and var
    
    async function javed() {
      // the function is async, so it always returns a Promise. No await necessary.
      return createMap();
    }
    
    function createMap() {
      var map2 = new Map();
      map2.set('11', true);
      map2.set('22', true);
      map2.set('33', false);
      map2.set('44', true);
      return map2;
    }
    
    function Dome(res) {
      res.forEach(x => {
        console.log('inside dome', x);
      })
    }
    
    
    console.log("before javed");
    // call javed, then Dome without a top level async function but the then method of a Promise:
    // less verbose than javed().then(function(resolvedMap){Dome(resolvedMap)});
    javed().then(Dome);
    console.log("this will be executed before the callback function Dome!");
    Login or Signup to reply.
  2. The returned value of an async function is a promise so you have to resolve it with await or .then():

    async function javed(){
    
      var map1 = new Map();
    
      map1 = await createMap();
    
    
      return map1;
    
    
     }
    
     function createMap(){
    
      var map2 = new Map();
      map2.set('11', true);
      map2.set('22', true);
      map2.set('33', false);
      map2.set('44', true);
    
      return map2;
    
    
     }
    
      this.javed().then(x => this.Dome(x));
      
     
      (async()=>{
    
        const x = await this.javed();
        this.Dome(x);
      
      })();
    
    
    
      function Dome(res){
    
        res.forEach(x =>{
          console.log('inside dome', x);
    
        })
    
      }

    A third option would be using only await in a top-level of a module:

    <script type="module">
    
    async function javed(){
    
      var map1 = new Map();
    
      map1 = await createMap();
    
    
      return map1;
    
    
     }
    
     function createMap(){
    
      var map2 = new Map();
      map2.set('11', true);
      map2.set('22', true);
      map2.set('33', false);
      map2.set('44', true);
    
      return map2;
    
    
     }
    
     const x = await javed();
     Dome(x);
    
    
    
      function Dome(res){
    
        res.forEach(x =>{
          console.log('inside dome', x);
    
        })
    
      }
    
    </script>
    Login or Signup to reply.
  3. You are trying a forEach over a promise.
    The method below is an async method, but it can return the value without async/await because createMap is not returning a promise.

    async function javed(){
      var map1 = new Map();
    
      map1 = await createMap();
    
    
      return map1;
    
     }
    

    OR

    You need to use .then to get the value asynchronous like below

    javed()
       .then(res => {
          Dome(res);
       });
    

    Take a look on this explanation

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search