0

The async/await function search returns an object similar to:

[
  {
    "title":"page title",
    "url":"/page/url/index.html",
    "content":"blah blah blah"
  },
  ...
]

I need to push each object from val into the array, but when I push using:

results = [];
search(input).then(val=> results.push(val));

I get a nested array similar to (I want to the object entries to be top level in the array):

[
  [
    {title:"...", url:"...", content:"..."},
    {title:"...", url:"...", content:"..."},
  ]
]

So I tried a for in the arrow to push each entry in the object into the array, but that didn't seem to work.

results = [];
search(input).then(val=> for(i in val) {results.push(val[i])});
3
  • 4
    Try this: search(input).then(val=> results.push(...val)); Commented Aug 19, 2020 at 14:26
  • 1
    Can't you just use results = val? although I don't really see a purpose of doing this as you'll only be able to access the populated version of results once your promise has resolved, such as in the .then() callback, so you might as well just use val Commented Aug 19, 2020 at 14:27
  • Try search(input).then(val=> [].concat(results, val)); Commented Aug 19, 2020 at 14:33

4 Answers 4

3

Instead of .push(), use .concat()

results = [];
search(input).then(val=> { results = results.concat(val) });
Sign up to request clarification or add additional context in comments.

Comments

2

Use spread syntax ...

No For loop needed either.

search(input).then(val=> results = [...results,...val]);

or as @Patrick_Hund suggested

search(input).then(val=> results.push(...val));

here problem is that you are pushing array in to an array.

You need to push the elements of array.

Spreading syntax should fix the issue.

Hope you have clear understanding now.

3 Comments

push accepts an arbitrary number of arguments, so you can just use the spread operator on val to push to results: search(input).then(val=> results.push(...val));
you don't need a for loop here
@PatrickHund - post yours as an answer, and I'll accept. Thanks.
2

If you have an array and call a function that will return Promise<array> you don't need to perform any iteration on the result. Concatenate the arrays:

async function getNewData() {
  return Promise.resolve([{
    d: 1
  }, {
    e: 3
  }]);
}

let results = [{
  a: 3
}, {
  b: 4
}];

getNewData().then(newdata => {
  results = results.concat(newdata); 
  // same as results = [...results, ...newdata];

  console.log(results);
});

On the other hand, you could also push using the spread operator

async function getNewData() {
  return Promise.resolve([{
    d: 1
  }, {
    e: 3
  }]);
}

const results = [{
  a: 3
}, {
  b: 4
}];

getNewData().then(newdata => {
  results.push(...newdata); 
  // same as results.push(newdata[0], newdata[1], etc)

  console.log(results);
});

This approach might be confusing as people tend to ignore the variadic nature of Array.prototype.push, but it avoids redeclaring results, so you may declare the target array as const.

Comments

1

If you want to use a for loop, you'll have to do

for(var i=0; i < val.length; i++) {
    results.push(val[i])
}

There are more succinct ways to do this (see Patrick Hund's comment), but that's how you do it with a for loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.