Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Array Iteration Methods Combining Array Methods Nested Data and Additional Exploration

Question about method chaining

Can someone help explain what is happening in the video when Joel uses method chaining to return the array of user favorite books? I got the correct result with another combination of methods, but I want to comprehend Joel's approach using inner functions. I've been tackling these small challenges modularly by applying a method, logging the returned value, then applying the next one as needed. This has been helpful because it makes clear what method needs to be applied and what the callback should look like. However, I can't seem to break down Joel's approach the same way because of the order of chaining. Okay rambling done, here's the code.

const users = [
  {
    name: 'Samir',
    age: 27,
    favoriteBooks:[
      {title: 'The Iliad'},
      {title: 'The Brothers Karamazov'}
    ]
  },
  {
    name: 'Angela',
    age: 33,
    favoriteBooks:[
      {title: 'Tenth of December'},
      {title: 'Cloud Atlas'},
      {title: 'One Hundred Years of Solitude'}
    ]
  },
  {
    name: 'Beatrice',
    age: 42,
    favoriteBooks:[
      {title: 'Candide'}
    ]
  }
];

let books = users
  .map(user => user.favoriteBooks.map(book => book.title))  // What is happening here?
  .reduce((newArray, books)=>{ 
    return [...newArray, ...books]
  }, []);

/***
Why doesn't the following code work? I think I might be confused about how inner functions work. 
let books = users
  .map(user => user.favoriteBooks)
  .map(book => book.title)
  .reduce((newArray, books)=>{
    return [...newArray, ...books]
  }, []);
***/

/***
My solution
let userFavs = users
  .map(user => user.favoriteBooks)
  .reduce((newArray, books) => {
    return [...newArray, ...books]
  }, [])
  .map(book => book.title)
***/

Cheers and Thanks in Advance!

Michael

I may have answered my own question. Mapping over users and returning user.favoritebooks returns an array of arrays containing objects, which makes it harder to access those titles. That's why in my solution I had to use reduce to flatten the array. When map is chained onto user.favoritebooks within the initial map method (instead of being applied to the returned value) you end up with an array of arrays. If I'm still thinking about this incorrectly please let me know!

1 Answer

Matthew Lang
Matthew Lang
13,483 Points

There's a LOT going on here, and it is definitely hard to wrap your head around it. First of all, you should make yourself familiar with ES6 (ES2015) JavaScript, which includes this arrow-function syntax.

(first, second) => { return first+second }

This is an anonymous function, hence why it does not have a name. Instead, it simply has the parenthesis to store the function parameters, then an arrow => then the standard code block using curly brackets. You can read more about this here. It's crucial you understand this concept.

Method Chaining Method chaining is great!

Observe this code excerpt:

let str = "Hello, world.";
console.log(str.toUpperCase().substring(7));

Thanks to method chaining and dot notation, I can simply add additional methods on the end of my string. This particular code simply prints "WORLD.", as it makes everything upper case, then cuts the string from the 8th character (starts at 0).

I hope this allows you to understand the code better. If you need help with the map function, please read this