Show different list items if user is logged in or not

Viewed 52

I have an array of possible side nav items that i want to render to the screen. The guest user should only see 2 of the items and when the user logs in he should be able to see all 3 of them. How would I not render the first item in the list if the user is not logged in?

apps: Array<SideNavItemModel> = [
{
  title: "sideNav.centralWeighingLink",
  url: "centralWeighing",
  id: "1",
  icon: "mdi-scale-balance",
  isAuthorized: false
},
{
  title: "sideNav.appsLink",
  url: "apps",
  id: "2",
  icon: "mdi-apps"
},
{
  title: "sideNav.2Link",
  url: "password",
  id: "3",
  icon: "mdi-key-variant"
},
]; 

I have a mounted method that checks if the $auth.user object is not null, and it then sets the value of isAuthorized to true.

This is the code that renders the list now:

    <v-list dense>
    <v-list-item v-for="app in apps" :key="app.id"
                 active-class="router-link-active" :to="`/${app.url}`" link>
      <div v-if="!$auth.user && app.isAuthorized === false ">
        <v-list-item-icon>
          <v-icon>{{ app.icon }}</v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ $t(app.title) }}</v-list-item-title>
        </v-list-item-content>
      </div>
    </v-list-item>
  </v-list>

I dont know how to write this block so that it would ommit the first item in the list without hardcodding it somehove, since this line below doesnt work.

v-if="!$auth.user && app.isAuthorized === false

I know that using the loggedIn method would be easier but I cannot used it because of the way the app is built currently.

3 Answers

If you want to show the first item after user logged in, just need to change the condition of the first item.

Init apps like this:

apps: Array<SideNavItemModel> = [
  {
    title: "sideNav.centralWeighingLink",
    url: "centralWeighing",
    id: "1",
    icon: "mdi-scale-balance",
    isAuthorized: false
  },
  {
    title: "sideNav.appsLink",
    url: "apps",
    id: "2",
    icon: "mdi-apps",
    isAuthorized: true
  },
  {
    title: "sideNav.2Link",
    url: "password",
    id: "3",
    icon: "mdi-key-variant",
    isAuthorized: true
  },
]; 

And then render the list like this:

 <v-list dense>
    <v-list-item v-for="app in apps" :key="app.id"
                 active-class="router-link-active" :to="`/${app.url}`" link>
      <div v-if="app.isAuthorized">
        <v-list-item-icon>
          <v-icon>{{ app.icon }}</v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ $t(app.title) }}</v-list-item-title>
        </v-list-item-content>
      </div>
    </v-list-item>
  </v-list>

After user has logged, just need to set the first app's isAuthorized as true.

Just saying my thoughts, hope it helps.

After the user logged in, store the token in the store with mutations. Note that it will be a string but you should convert it into a boolean using !!. '' = false but ' ' is true.
This is all you need.

new Vue({
  el: '#app',
  data() {
    return {
      hello: 'hellasdfo',
      token: false,
    }
  },
  created() {
    // store in store and get it with getters
    // this.token = !!this.$store.getters['token'] or !!this.$store.getters.token
    this.token = !!'some token';
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <p>Not LoggedIn</p>
  <p>Not LoggedIn</p>
  <p v-if="token">LoggedIn</p>
</div>

As you are assigning isAuthorized property in each object in an array and then based on the $auth.user you are setting it as true/false. Then we can simply achieve that by updating the flag in the created() hook.

Live Demo :

new Vue({
  el: '#app',
  data: {
    apps: [
      {
        title: "sideNav.centralWeighingLink",
        url: "centralWeighing",
        id: "1",
        icon: "mdi-scale-balance"
      },
      {
        title: "sideNav.appsLink",
        url: "apps",
        id: "2",
        icon: "mdi-apps"
      },
      {
        title: "sideNav.2Link",
        url: "password",
        id: "3",
        icon: "mdi-key-variant"
      }
    ],
    isLoggedInUser: false
  },
  created() {
    if (this.isLoggedInUser) {
        this.apps.forEach(obj => obj.isAuthorized = true)
    } else {
        this.apps.forEach((obj, index) => {
        obj.isAuthorized = (index) ? true : false
      })
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="app in apps" :key="app.id">
    <li v-if="app.isAuthorized">{{ app.url }}</li>
  </div>
</div>

Related