0

I am building a simple todo app, and I'm trying to get the assigned users for each task. But let's say that in my database, for some reason, the tasks id starts at 80, instead of starting at 1, and I have 5 tasks in total.

I wrote the following code to get the relationship between user and task, so I would expect that at the end it should return an array containing 5 keys, each key containing an array with the assigned users id to the specific task.

Problem is that I get an array with 85 keys in total, and the first 80 keys are undefined.

I've tried using .map() instead of .forEach() but I get the same result.

let assignedUsers = new Array();

this.taskLists.forEach(taskList => {
    taskList.tasks.forEach(task => {
        let taskId = task.id;
        assignedUsers[taskId] = [];

        task.users.forEach(user => {
            if(taskId == user.pivot.task_id) {
                assignedUsers[taskId].push(user.pivot.user_id);
            }
        });
    });
});

return assignedUsers;

I assume the issue is at this line, but I don't understand why...

assignedUsers[taskId] = [];

I managed to filter and remove the empty keys from the array using the line below:

assignedUsers = assignedUsers.filter(e => e);

Still, I want to understand why this is happening and if there's any way I could avoid it from happening.

Looking forward to your comments!

6
  • How/where is assignedUsers declared? Commented May 1, 2019 at 21:46
  • @Pointy It's defined right above the first .forEach() Commented May 1, 2019 at 21:55
  • Well it is now, but it wasn't when I posted that comment. So what are those taskId values? Numbers? If not, you should not be using an array. Commented May 1, 2019 at 21:57
  • 1
    true, I added after reading your comment for future users reading this. Commented May 1, 2019 at 21:58
  • Are you sure that those ser.pivot.user_id values are not undefined? Commented May 1, 2019 at 22:00

3 Answers 3

4

If your taskId is not a Number or autoconvertable to a Number, you have to use a Object. assignedUsers = {};

Sign up to request clarification or add additional context in comments.

2 Comments

indeed, it is! @Asthmatic
@Kai Lehmann, thanks for sharing this quick and easy fix! It worked like a charm!
1

This should work as you want it to. It also uses more of JS features for the sake of readability.

return this.taskLists.reduce((acc, taskList) => {
    taskList.tasks.forEach(task => {
        const taskId = task.id;
        acc[taskId] = task.users.filter(user => taskId == user.pivot.task_id);
    });
    return acc;
}, []);

But you would probably want to use an object as the array would have "holes" between 0 and all unused indexes.

3 Comments

So, the undefined keys are caused by using an array instead of an object?
@MattE.Very possibly, but hard to tell without the actual data.
It seems that the issue is caused by using an array instead of an object. There's already someone who pointed that out first, so I am giving the correct answer to him, but thanks for helping out and sharing your code. Btw, I tried your code too, but unfortunately it isn't working as I would expect, since it's returning the whole user instead of an array of user ids.
0

Your keys are task.id, so if there are undefined keys they must be from an undefined task id. Just skip if task id is falsey. If you expect the task id to possibly be 0, you can make a more specific check for typeof taskId === undefined

this.taskLists.forEach(taskList => {
    taskList.tasks.forEach(task => {
        let taskId = task.id;
        // Skip this task if it doesn't have a defined id
        if(!taskId) return;
        assignedUsers[taskId] = [];

        task.users.forEach(user => {
            if(taskId == user.pivot.task_id) {
                assignedUsers[taskId].push(user.pivot.user_id);
            }
        });
    });
});

5 Comments

Don't use x===undefined. It can cause problems. Using typeof x === 'undefined' is save. Read more at developer.mozilla.org/de/docs/Web/JavaScript/Reference/…
@Asthmatic unfortunately this doesn't work. I've tried both checks if(!taskId) return and if(typeof taskId === 'undefined') and I still get back 85 keys in the array...
Ok. It's 85 because your first taskId is obviously 4. If your tasks don't have consecutive indexing, you can't use an array in javascript. stackoverflow.com/questions/4771001/…
Quick proof: let a = new Array(); a[5] = "test"; -> a[0] through a[4] will be empty indexes
@Asthmatic, good point! I didn't know that before today. I'm pretty new with Javascript and I come from PHP world where things are a little bit more clear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.