DEV Community

loading...
Cover image for Turn Object to Array using Object.entries()

Turn Object to Array using Object.entries()

Oryam
Junior Web developer
・2 min read

For most cases the easiest way for manipulating and displaying data with Javascript is when it is organized as an array of objects.
Usually, we get data like that from an api. But in some cases, the data is organized as nested objects.

The problem

While working on a Crypto currency SPA project we used cryptocompare API
to compare crypto coins to USD.
The returned data looks something like this (json format):

{"BTC":{"USD":18188.04},"ETH":{"USD":557.07}}
Enter fullscreen mode Exit fullscreen mode

But we wanted it to be organized like:

  [
    {name:"BTC",currency:"USD",value:'181.88.04'}, 
    {name:"ETH",currency:"USD",value:'557.07'}
  ]
Enter fullscreen mode Exit fullscreen mode

The solution

So we googled...
and found out about Object.entries(obj)

part 1

This method returns an array. Each item in the array is another array that has the first item as a key and the second as its key value.

It looks like this:

const coins = { BTC: { USD: 18188.04 }, ETH: { USD: 557.07 } };

console.log(Object.entries(coins));
//[ [ 'BTC', { USD: 18188.04 } ], [ 'ETH', { USD: 557.07 } ] ]
Enter fullscreen mode Exit fullscreen mode

part 2

Ok, this is a good start. Now we can use map() to turn it into an array of objects.

And it should look like:

coinsToArr = coinsToArr.map(([name, data]) => ({ name, data }));
// [ { name: 'BTC', data: { USD: 18188.04 } }, { name: 'ETH', data: { USD: 557.07 } } ]
Enter fullscreen mode Exit fullscreen mode

part 3

Now it looks much better and easier to work with. But it's not exactly what we wanted to achieve.
We have the same kind of problem but now the object is nested in the new object we created.

Assuming we will get only one currency each time we used the same method as above inside the first map function :

coinsToArr = coinsToArr.map(([name, data]) => {
  data = Object.entries(data); 
  data = data.map(([currency, value]) => ({ currency, value }));
  return {
    name,
    currency: data[0].currency,
    value: data[0].value,
  };
});

// [ { name: 'BTC', currency: 'USD', value: 18188.04 }, { name: 'ETH', currency: 'USD', value: 557.07 }]
Enter fullscreen mode Exit fullscreen mode

Now this is what we wanted.

part 4

Refactoring and turning it into a function

const coinsObjToArr = (obj) => {
//using Object.entries().map()
  return Object.entries(obj).map(([name, data]) => {
//getting the currency and value using Object.entries().map() 2nd time
    const { currency, value } = Object.entries(data).map(
      ([currency, value]) => ({
        currency,
        value,
      })
// getting the first and only item from the array
    )[0]; 
    return {
//return all values as object
      name,
      currency,
      value,
    };
  });
};
Enter fullscreen mode Exit fullscreen mode

I know it might look hard to understand because of all the destractuaring and chaining methods but it's just all the parts connected.

We simply used Object.entries() and map() twice, nested.

References:

Hope it was helpful.

Discussion (2)

Collapse
vonheikemen profile image
Heiker

That feels like a lot of work. If you are looping through a plain object the for..in loop could help.

This works.

function format_response(response) {
  let result = [];

  for(let crypto in response) {
    let data = { name: crypto };
    for(let currency in response[crypto]) {
      data.currency = currency;
      data.value = response[crypto][currency];
    }
    result.push(data);
  }

  return result;
}

const data = {"BTC":{"USD":18188.04},"ETH":{"USD":557.07}};
format_response(data);
Enter fullscreen mode Exit fullscreen mode
Collapse
oryam profile image
Oryam Author

Thanks, interesting!
I'm sure there is more than one solution for this type of problem. I just wanted to share with something new I learned.