Daniel Rg
Daniel Rg

Reputation: 35

Get a new Array from an Object with multiple arrays

I am getting a very big object from my API Endpoint back. It is an object with multiple arrays. In each of them as an url (items.[0].images[0].url for example). I would like to create a new Array, just with the urls and store them in my Redux store.

I have tried to use a filter method, but I am getting back the same big Array every time, without any changes.

Furthermore, I notice if I console.log(typeof res.data.items) I am getting an object instead of an array as an output. I am a just confused, because my console is also saying res.data.items is an array.

Thats a part of my res object

{data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
config: {url: "/me/top/artists?limit=20&offset=11", method: "get", headers: {…}, baseURL:    "https://api.spotify.com/v1", transformRequest: Array(1), …}



data:
href: "https://api.spotify.com/v1/me/top/artists?limit=20&offset=11"
items: Array(20)
0:
external_urls: {spotify: "https://open.spotify.com/artist/0fA0VVWsXO9YnASrzqfmYu"}
followers: {href: null, total: 4774667}
genres: (3) ["hip hop", "ohio hip hop", "rap"]
href: "https://api.spotify.com/v1/artists/0fA0VVWsXO9YnASrzqfmYu"
id: "0fA0VVWsXO9YnASrzqfmYu"
images: Array(3)
     0:
         height: 640
          url: "https://i.scdn.co/image/4cb57ae1ef87546455db9cf65ba414c311ff459a"

1: {…}
2: {…}

....

that's my function

.then((res) => {
      ***let newdata = res.data.items.filter((url) => url.images[0].url)*** // not working

      console.log('newdata', newdata) // getting back res.data.items

      console.log(res.data.items) // Array
      console.log('res', res)
      console.log(typeof res.data.items) // Object ?
      dispatch({
        type: FETCH_TOP_25_ALBUMS,
        payload: newdata,
      })
    })

Upvotes: 0

Views: 430

Answers (2)

Ben Wainwright
Ben Wainwright

Reputation: 4621

.filter() doesn't do what you think it does. Filter takes a "predicate", that is a function which takes an input and returns either true or false. It then applies that function to each array element and returns an array containing only the elements where the predicate returned true.

So in the case of

[1, 2, 3, 4, 5].filter(item => item > 3)

You would get a return value of [4, 5], because only 4 and 5 return true when applied to the predicate item => item > 3

In your case your filter function is res.data.items.filter((url) => url.images[0].url). Since your predicate is just returning the value of the url field, your predicate is always going to return true unless the url field is set to either

  1. undefined
  2. null
  3. "" (an empty string)

That's almost certainly not the case in any of your data, so entire array is being returned.

What you are trying to do is take an array where each element has shape X and map it to an array where each element has shape Y. For this you need .map()

Try the following:

res.data.items.map(item => item.images[0].url)

This will take the contents of the res.data.items array, and replace each element with the return value of the function passed in when supplied with the value of that element.

Upvotes: 0

T J
T J

Reputation: 43156

To create a new Array, you can use Array.map(). Try

let newdata = res.data.items.map(item => item.images[0].url)

Upvotes: 1

Related Questions