Search code examples
vue.js

How can i make a class in vue based on a condition from a database


I have multiple div elements with a class based on a special condition. I'm checking this condition once I receive data from a database. The problem is the component is rendered before receiving the data from a database. I've tried to make an async function and use await, but it didn't work. (I'm not very proficient in JS and Vue)

Component:

<v-table v-if="allActions.length != 0">
  <thead>
    <tr>
      <th class="text-center text-blue" :colspan="lastWeekCount + 1">Недели</th>
    </tr>
    <tr>
      <th class="text-left text-blue">Actions</th>
      <th v-for="week in 15" :key="week" class="text-center text-blue">
        {{ week + firstWeekCount - 1 }}
      </th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="action in allActions" :key="action">
      <td>{{ action.reason }}</td>
      <td v-for="week in 15" :key="week" class="text-center">
        <div>
          <v-dialog max-width="500">
            <template
              v-slot:activator="{
                props: activatorProps,
              }"
            >
              <div
                v-if="checkActionStatus(week + firstWeekCount - 1, action.id)"
                @click="selectChosenAction(week + firstWeekCount - 1, action.id)"
                v-bind="activatorProps"
                :class="checkActionStatus(week + firstWeekCount - 1, action.id)"
                style="height: 15px; width: 15px"
              ></div>
            </template>

            <template v-slot:default="{ isActive }">
              <v-card title="Change a status">
                <v-card-text>
                  <v-select
                    v-model="chosenAction.status"
                    :items="['OK', 'nOK', 'Empty']"
                    label="Status state"
                    :disabled="isStatus"
                    item-title="name"
                    return-object
                    variant="solo"
                  ></v-select>
                  <div v-if="isStatus" class="text-red-lighten-1">
                    Action is already chosen
                  </div>
                </v-card-text>
                <v-card-actions>
                  <v-spacer></v-spacer>
                  <v-btn text="Close" @click="isActive.value = false"></v-btn>
                  <v-btn
                    class="ma-2"
                    color="success"
                    variant="flat"
                    v-bind="props"
                    @click="updateChosenAction"
                    >Save</v-btn
                  >
                </v-card-actions>
              </v-card>
            </template>
          </v-dialog>
        </div>
      </td>
    </tr>
  </tbody>
</v-table>

function with async await:

const checkActionStatus = async (week, action_id) => {
  try {
    const response = await httpServer.post("selectActionByWeek", { week: week, action: action_id });
    if (response.data[0]) {
      switch (response.data[0].status) {
        case 'Empty':
          return "bg-blue-grey-lighten-3 rounded-circle mx-auto";
        case 'OK':
          return "bg-light-green-accent-3 rounded-circle mx-auto";
        case 'nOK':
          return "bg-amber-lighten-2 rounded-circle mx-auto";
        default:
          return "bg-blue-grey-lighten-3 rounded-circle mx-auto";
      }
    } else {
      return "bg-blue-grey-lighten-3 rounded-circle mx-auto";
    }
  } catch (error) {
    console.log(error);
    return "bg-blue-grey-lighten-3 rounded-circle mx-auto";
  }
};

Solution

  • OP moved his calls to an @click, getting some inspiration on this other answer also helped a bit.