Search code examples
javascriptreactjsfilteres6-map

ReactJS | Show or Hide Array of Objects based on flag


The Problem: What I am trying to do is hide/show react elements that are constructed dynamically based on a property of the Object Constructed. To be more precise let's take the following Array of Objects:

const Apps = [
  {name: App1, permission: ViewApp1},
  {name: App2, permission: ViewApp2},
  {name: App3, permission: ViewApp3},
  {name: App4 },
]

I want to map through them, and for each item, create a nav-item, in my NavBar.

Here is the jsx code for that:

const ScreenModule = ({ apps = [], currentRoute }) => (
  <Fragment>
    {apps.map(app => (
      <li
        key={app.name}
        title={app.name}
      >
        <a href={getUrlLink(app)}>
          <span>{app.name}</span>
        </a>
      </li>
    ))}
  </Fragment>
);

Now, usually when I want to check when to show an element, I wrap that jsx element, in the following utility function:

const AuthViewAdminManagement = ConditionalLoader(({ user }) =>
  // user = The currently loggedIn user
  userHasPermission(user, [
    Role.ViewApp1 // My ConstantArray of Permissions to check against
  ])
);

That is for a static element. My problem lies on how to do the exact same thing for my dynamically constructed apps.

Basically, I am trying to find a way to wrap the li conditionally, based on the name or the permission.

Also, how to deal with App4 that doesn't have permission. How to show/hide that one in the map.

I thought about using a filter, filtering for specific permissions or name, but I got stuck.

I hope I made clear what my problem is. If you can help, it would be great. Thank you!


Solution

  • You can filter:

    const ScreenModule = ({ apps = [], currentRoute }) => (
      <Fragment>
        {apps.filter(app => app.permission).map(app => {
           return <li
             key={app.name}
             title={app.name}
           >
             <a href={getUrlLink(app)}>
               <span>{app.name}</span>
             </a>
           </li>
         })}
      </Fragment>
    );