Search code examples
javascriptreactjslodash

How can I map over and object, that contains another Object I want to map over and return JSX from it?


My Problem

I have mockdata Object that looks like that:

topicGroups: {
    0: {
      title: "Languages",
      topics: {
        0: {
          title: "Javascript",
          description: "Everything about Vanilla JS",
          latestTopic:
            "Diskussion] Der ideale asdf Gaming-PC er ideale asdf Gamin(1..."
        },
        1: {
          title: "C#",
          description: "Microsoft's go to language",
          latestTopic: "Main geiles Topic alter"
        }
      }
    },
    1: {
      title: "Coding Partner Search",
      topics: {
        0: {
          title: "Suche nach Liebe",
          description: "Everything about Vanilla JS",
          latestTopic:
            "Diskussion] Der ideale asdf Gaming-PC er ideale asdf Gamin(1..."
        }
      }
    }
  }

I want to achieve the following:

  • Map over all the topics groups (to get access to the title string and topics object.
  • Map over the topics object inside the first map (so I'm in scope for the group title)
  • Return Jsx where I use just the group's title and current topic title and description

I tried it with several lodash functions, but I can't make it work. The closest I got was to create another fresh object besides topicGroups, but then it is difficult to figure out which topics refers to which topicGroups.

Example how I want to use the jsx and what I want to return:

return groups.map(group =>
      group.topics.map(topic => {
        return (
          <ForumTopicGroup title={group.title}>
            <ForumTopic>{topic.title}</ForumTopic>
          </ForumTopicGroup>
        );
      })
    );

What is the best and most clean way to achieve this?

The reason why I have my data like only with object instead of using arrays is, because I want to work with this data like it comes from firebase (as I will use firebase later on in the application


Solution

  • It would work like you have written it in your question if you could use arrays, but since objects don't have a map method, you could use Object.entries instead to iterate over all the key-value pairs in the objects.

    Example

    const groups = {
      0: {
        title: "Languages",
        topics: {
          0: {
            title: "Javascript",
            description: "Everything about Vanilla JS",
            latestTopic:
              "Diskussion] Der ideale asdf Gaming-PC er ideale asdf Gamin(1..."
          },
          1: {
            title: "C#",
            description: "Microsoft's go to language",
            latestTopic: "Main geiles Topic alter"
          }
        }
      },
      1: {
        title: "Coding Partner Search",
        topics: {
          0: {
            title: "Suche nach Liebe",
            description: "Everything about Vanilla JS",
            latestTopic:
              "Diskussion] Der ideale asdf Gaming-PC er ideale asdf Gamin(1..."
          }
        }
      }
    };
    
    function App() {
      return (
        <div>
          {Object.entries(groups).map(([groupKey, group]) => (
            <div key={groupKey}>
              {Object.entries(group.topics).map(([topicKey, topic]) => {
                return (
                  <div key={topicKey}>
                    {group.title} - {topic.title}
                  </div>
                );
              })}
            </div>
          ))}
        </div>
      );
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="root"></div>