Title: Is there a way to fill the JSON object before resolving the promise
Tags: javascript;json;for-loop;promise
Question: the code first gets all the urls from the database.
and in parseText i'm trying to parse all the ur's and put them in an Json object for later reference.

i've tried running the for loop with async/await, but that didnt give me the expected result.

```let parseText = function(dbresult) {
    return new Promise((resolve, reject) =&gt; {
    let textObj = {}

    for(i=0; i < dbresult; i++) {
       Mercury.parse(dbresult[i].url, {headers: {Cookie: 'name=Bs', 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', },})
       .then((result) =&gt; {
           textObj[dbresult[i].id] = result.excerpt;
      });
    }
    resolve(textObj);
  })
}


fetchLinks.then(function(result) {
    return parseText(result);
  }).then(function(result) {
  console.log(result); //gives back {}
  //do something with json object in next promise
  return writeTextToDb(result); //not written yet
})
```

the desired output should look something like {1234 : {text: some parsed text}}, but all i keep getting is an empty object

Comment: What data type is `dbresult`? I'm pretty sure you messed up your terminating condition for your `for` loop. It should be `i < dbresult.length`


Here is another answer: There are multiple things to tackle in your code, so let's go step by step:


```dbresult``` seems to be an array, judging by your use of ```dbresult[i]```, but you also have a ```i < dbresult``` condition that implies it's an integer.  I'm going to asume you meant ```i < dbresult.length```.
You are using ```new Promise(...)``` in a situation where you are already dealing with promises.  You should never use this pattern unless you don't have an alternative, and always try to chain ```.then``` calls and return their results (which are always also promises).
You seem to have failed to understand that the callback passed to ```.then``` will always run asynchronously, after the rest of the code runs.  This is the reason your object comes out empty:  the ```resolve``` function is called before any of the requests have time to complete.


Now, loops and promises don't mix very well, but there are ways of dealing with them.  What you need to anderstand is that, with loops, what you want is to chain promises.  There are mostly two ways of chaining promises in this way:  the imperative way and the functional way.

I'm going to focus on the ```parseText``` function and omit irrelevant details.  This is what you would do for a fully imperative solution:

```function parseText (dbresult) {
    // although the contents of the object change, the object doesn't,
    // so we can just use const here
    const textObj = {};

    // initialize this variable to a dummy promise
    let promise = Promise.resolve();

    // dbresult is an array, it's clearer to iterate this way
    for (const result of dbresult) {
       // after the current promise finishes, chain a .then and replace
       // it with the returned promise.  That will make every new iteration
       // append a then after the last one.
       promise = promise
         .then(() =&gt; Mercury.parse(result.url, {...}))
         .then((response) =&gt; (textObj[result.id] = response.excerpt));
    }

    // in the end, the promise stored in the promise variable will resolve
    // after all of that has already happened.  We just need to return the
    // object we want to return and that's it.
    return promise.then(() =&gt; textObj);
}
```

I hope the comments help.  Again, working with promises in a loop sucks.

There are two ways of doing this in an easier way, though! both use the functional methods of arrays.  The first one is the easiest, and it's the one I'd recommend unless the array is going to be very big.  It makes use of ```.map``` and ```Promise.all```, two powerful allies:

```function parseText (dbresult) {
    const textObj = {};

    // create an array with all the promises
    const promises = dbresult.map(result =&gt; Mercury.parse(result.url, {...})
        .then((response) =&gt; (textObj[result.id] = response.excerpt)))
    );

    // await for all of them, then return our desired object
    return Promise.all(promises).then(() =&gt; textObj);
}
```

```
  Note: ```bluebird``` users can make this even better using ```Promise.map``` and passing a ```concurrency``` value.  That is actually, in my opinion, the best solution, but I want to stick with vanilla here.
```

The main problem with this solution, though, is that all request will be kellygrant@example.net.  This might mean that, for very large arrays, some requests just wait in a queue or you exhaust the socket limit of the process, depending on the implementation.  In any case, it's not ideal, but for most situations will work.

The other functional solution consists of replicating the imperative one using ```.reduce``` instead of a ```for ... of``` loop, and it's implemented at the end of the answer, more as a curiosity than anything else, as I think it's a bit too "clever code".

In my opinion, the best way of solving this is to just use ```async/await``` and forget promises altogether.  You can just write your loop normally in this case and simply put await where appropriate:

```async function parseText (dbresult) {
    const textObj = {};

    for (const result of dbresult) {
        // here just await the request, then do whatever with it
        const response = await Mercury.parse(result.url, {...}))
        textObj[result.id] = response.excerpt;
    }

    // thanks to await, here we already have the result we want
    return textObj;
}
```

That's it, it's that simple.



And now for what I consider to be the "clever" solution, using only ```.reduce```:

```function parseText (dbresult) {
    const textObj = {};
    return dbresult.reduce(
        (prom, result) =&gt; prom
            .then(() =&gt; Mercury.parse(result.url, {...}))
            .then((response) =&gt; (textObj[result.id] = response.excerpt)),
        Promise.resolve()
    ).then(() =&gt; textObj);
}
```

If it's not immediately clear what it does, that's normal.  This does exactly the same thing as the original imperative ```then```-chaining one does, just using ```.reduce``` instead of a manual ```for``` loop.

Note that I personally wouldn't necessarily do this, as I think it's a bit too "clever" and takes some time to parse mentally.  If implementing something like this (```then```-chaining using ```.reduce``` is incredibly useful, even if a bit confusing) please add a comment explaining why you did this, what it is, or something that can help other developers understand ir at first glance.

Comment for this answer: *"... I'm not going to write it because it's ridiculously "smart" and will trump even the more experienced developers"* Now you got me curious, by all means please post it. +1 BTW well written.
Comment for this answer: thank you so much, the .length i didnt see right away, but that wasn't the problem. because of this explanaition i managed to continue and even finish the code for now. many thanx
Comment for this answer: @zer00ne there you go. Maybe it's less clever than I think, but I read something like it a while ago while debugging something and it took me a while to understand what the hell was happening.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2019:00:06/17/19', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<javascript><json><for-loop><promise>', 'Title': 'Is there a way to fill the JSON object before resolving the promise', 'ViewCount': 73, 'id': 56639950, 'user_AboutMe': None, 'user_AccountId': 16153717.0, 'user_DisplayName': 'Manu S', 'user_Reputation': 1.0, 'user_Views': 2.0, 'user_id': 11661442.0}}