entio
entio

Reputation: 4283

How to create a computed based on another computed from composable

I'm learning composition API doing a simple todo app but then with multiple swim-lanes (todo, doing, done).

in useTasks.js composable I create "global" sourceTasks reactive, that later gets filled with data pulled from an API. Then it is reduced in tasks computed property, like this:

// useTasks.js

const sourceTasks = reactive({
    list: []
});

export default function useTasks() {
    const tasks = computed(() => {
        return sourceTasks.list.reduce(divideIntoSwimLanes, [])
    });

    ...

    return {
        tasks,
        loadTasks,
        createTask
    }
}

Nothing too complicated.

Then I've got this SwimLane component, that well... uses the tasks :)

// SwimLane.vue - setup

async setup(props) {
    const { status } = toRefs(props);

    const { tasks, createTask } = useTasks();

    return {
      tasks,
      label,
      createTask
    }
}
// SwimLane.vue - template
<single-task class="m-3" v-for="task in tasks[status]" :title="task.title" :id="task.id"/>

This works, but I don't find it elegant. I would prefer to create a new computed inside of SwimLane's setup, that holds the value of tasks for the given SwimLane. Putting it in the template obscures the logic.

I would expect this to work, but it does not, I think it loses the reactivity but I cant wrap my head around why:

// SwimLane.vue - alternative setup
const currentContextTasks = computed(() => {
    return tasks.value[status]
});

return {
    currentContextTasks
}

The problem feels a bit ridiculous, but my main concern is that I have misunderstood some core concept, hence this lengthy post.

Upvotes: 4

Views: 8140

Answers (1)

entio
entio

Reputation: 4283

This is like a biggest blunder ever. So, the post was really helpful as a form of talking to the rubber duck.

What I did forgot to do is to use the value of the status. Since it is a ref, I had to use it as follows:

const currentContextTasks = computed(() => {
    return tasks.value[status.value]  // 'status.value' and not just 'status'
});

Upvotes: 12

Related Questions