PickyTech
PickyTech

Reputation: 133

Javascript Some Method nested in For

The code below I am trying to see if one of the CrmRoles is in the list of rolesToVerify but I keep getting "undefined" for roleToVerify when I walk through it.

const rolesToVerify = ["System Administrator", "Payroll"]

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
    for (let currentUserRole of currentUserRoles) {
        return rolesToVerify.some(roleToVerify =>
           currentUserRole.Name === roleToVerify);
    }
    return false;
    }

Upvotes: 1

Views: 64

Answers (4)

PickyTech
PickyTech

Reputation: 133

const rolesToVerify = ["System Administrator", "Payroll"];

type CrmRole = { Name: string };

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
  for (let currentUserRole of currentUserRoles) {
    let roleExists =  rolesToVerify.some(roleToVerify => currentUserRole.Name === roleToVerify);

    if (roleExists) {
      return roleExists;
    }
  }

  return false;
}

console.log(userHasOneOrMoreRoles([{Name: 'horse'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: 'cow'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: rolesToVerify[0]}], rolesToVerify)); // Returns true
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: rolesToVerify[0]}], rolesToVerify)); // Returns true

const rolesToVerify = ["System Administrator", "Payroll"];

type CrmRole = { Name: string };

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
  for (let currentUserRole of currentUserRoles) {
    let roleExists =  rolesToVerify.some(roleToVerify => currentUserRole.Name === roleToVerify);

    if (roleExists) {
      return roleExists;
    }
  }

  return false;
}

console.log(userHasOneOrMoreRoles([{Name: 'horse'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: 'cow'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: rolesToVerify[0]}], rolesToVerify)); // Returns true
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: rolesToVerify[0]}], rolesToVerify)); // Returns true

I actually ended up with the code below, but the return inside the loop was the issue.

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
    for (let currentUserRole of currentUserRoles) {
        if (rolesToVerify.some(roleToVerify => currentUserRole.Name === roleToVerify)) {
            return true;
        }
    }
    return false;
}

Upvotes: 0

Mulan
Mulan

Reputation: 135377

What you're looking for is whether two sets have an intersection – only, you don't care about the particular intersecting values in this situation – you only care if some element in set X matches some element in set Y

Also this is tagged with functional programming, so we use expressions instead of statements

// hasIntersection :: ([a], [a]) -> Boolean
const hasIntersection = (xs = [], ys = [], x = 0, y = 0) =>
  y === ys.length
    ? false
    : x === xs.length
      ? hasIntersection (xs, ys, 0, y + 1)
      : xs [x] === ys [y] || hasIntersection (xs, ys, x + 1, y)

console.log (hasIntersection ([1, 2, 3], [4, 5, 6])) // false
console.log (hasIntersection ([1, 2, 3], [4, 1, 6])) // true
console.log (hasIntersection ([1, 2, 3], []))        // false
console.log (hasIntersection ([], [4, 5, 6]))        // false
console.log (hasIntersection ([], []))               // false

The input arrays can have values of any type – here the roles are integers, but you could use strings or another type you want

Upvotes: 1

Antonio Narkevich
Antonio Narkevich

Reputation: 4336

There are 2 problems. First, you are probably calling your function incorrectly cause for me it's partially working.

Second, there is a logical problem in your code: when you iterate over currentUserRoles array you do the return after the first iteration (the rest of the elements except the first one will be ignored).

Here's how it should look in my humble opinion:

const rolesToVerify = ["System Administrator", "Payroll"];

type CrmRole = { Name: string };

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
  for (let currentUserRole of currentUserRoles) {
    let roleExists =  rolesToVerify.some(roleToVerify => currentUserRole.Name === roleToVerify);

    if (roleExists) {
      return roleExists;
    }
  }

  return false;
}

console.log(userHasOneOrMoreRoles([{Name: 'horse'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: 'cow'}], rolesToVerify)); // Returns false
console.log(userHasOneOrMoreRoles([{Name: rolesToVerify[0]}], rolesToVerify)); // Returns true
console.log(userHasOneOrMoreRoles([{Name: 'horse'}, {Name: rolesToVerify[0]}], rolesToVerify)); // Returns true

Upvotes: 1

Thomas
Thomas

Reputation: 12657

You are returning inside a loop, independant of any condition or anything. There's no way, your loop gets past the first iteration.

//And you can shorten
rolesToVerify.some(roleToVerify => currentUserRole.Name === roleToVerify);
//to
rolesToVerify.includes(currentUserRole.Name);

so either

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
    for (let currentUserRole of currentUserRoles) {
        if(rolesToVerify.includes(currentUserRole.Name))
            return true;
    }
    return false;
}

or

function userHasOneOrMoreRoles(currentUserRoles: CrmRole[], rolesToVerify: String[]) {
    return currentUserRoles.some(currentUserRole => rolesToVerify.includes(currentUserRole.Name));
}

Upvotes: 1

Related Questions