Any way to loop through an object of arrays more efficiently to check for errors in function arguments?

Viewed 36

I am attempting to write a function that checks if the userId/channelId is valid by looping through the data store below.

let data = {
    users: [
      {
        uId: 1,
        email: 'kif@kmail.com',
        password: 'kif123',
        nameFirst: 'Kifaya',
        nameLast: 'Shehadeh',
        handle: 'kifayashehadeh',
      }, 
      {
        uId: 2,
        email: 'yus@ymail.com',
        password: 'yus1234',
        nameFirst: 'Yusra',
        nameLast: 'Mahomed',
        handle: 'yusramahomed',
      },
    ],
    channels: [
      { 
        channelId: 1,
        name: 'DREAM',
        ownerMembers: [1,2,3,4,5],
        allMembers: [1,2,3,4,5],
        isPublic: false,
        messages: [
          {
            messageId: 1,
            uId: 1,
            message: "Coffee is better at 12am.",
            timeSent: Math.floor((new Date()).getTime() / 1000),
          },
          {
            messageId: 2,
            uId: 2,
            message: "Chocolate is better 24/7.",
            timeSent: Math.floor((new Date()).getTime() / 1000),
          },
        ],
      },
      { 
        channelId: 2,
        name: 'COFFEE',
        ownerMembers: [1,2],
        allMembers: [1,2,3,4,5],
        isPublic: true,
        messages: [
          {
            messageId: 1,
            uId: 4,
            message: "Dark chocolate isn't even chocolate. Seriously.",
            timeSent: Math.floor((new Date()).getTime() / 1000),
          },
        ],
      },
    ],  
  };

This is currently the way I am doing it inside of a function:

//invalid channelId
let error = true;
    for (const channel of data.channels) {
      if (channel.channelId !== channelId ) {
        error = false;
      }
    }
    //invalid user
    for (const user of data.users) {
      if (user.uId === authUserId) {
        error = false;
      }
    }

    if (error === true) {
      return {
        error : 'error'
      }
    }

This method seems very inefficient and more like C than javascript, I was wondering if there were any magical single lines of code that could do some of that for me without being so unreadable. I am also finding a hard time figuring out how to make the error checking work correctly. Is there a way that allows me to return the error immediately so that it exits from the function the first time it detects an error?

1 Answers

I'd map both the users and the channels to just the properties you're interested in - .channelId and .uid - and then just use .includes twice to see that both values are included in both arrays.

const channelIds = data.channels.map(c => c.channelId);
const userIds = data.users.map(u => u.uId);
if (
  !channelIds.includes(channelId) ||
  !userIds.includes(authUserId)
) {
  return {
    error: 'error'
  };
}

It's possible to put into a single line, but it's less readable. (Technically, any JavaScript code could be put into a single line - but that doesn't make it a good idea from a maintainability standpoint.)

if (!data.channels.map(c => c.channelId).includes(channelId) || !data.users.map(u => u.uId).includes(authUserId)) { return { error: 'error' };}
Related