-1

UPDATE: this is NOT a question on javascript alone, but related to the javascript implementation on the MarkLogic platform. As the title of this question points out it is about the specific behaviour of the ValueIterator that is returned by the xdmp.userRoles() function.

I am trying to see if a user has a certain role in MarkLogic Security database, therefor I have done this :

declareUpdate();

var pid = '7610802';

// TODO validate that user can do this
var spo  = 'scc-proj-' + pid + '-owner';
var spm  = 'scc-proj-' + pid + '-member';
var spam = 'scc-proj-' + pid + '-adv-member';
// we need the security db Ids of these roles
var spoId = xdmp.role(spo);
var spamId = xdmp.role(spam);
var acceptedRoleIds = [spamId,spoId];

// get roleIds from sec db for this user
var userRoleIds = xdmp.userRoles('scc-user-1');
// map ValueIterator to array
var userRoleIdsArray = userRoleIds.toArray(); 

Now the userRoleIdsArray holds ids as unnsigned long like this:

[
"1088529792688125909", 
"1452323661308702627", 
"10258509559147330558", 
"10161853410412530308", 
"6677433310138437512", 
"12773061729023600875", 
"7482704131174481508", 
"3191093315651213021", <<<<< this is the one!!!
"5126952842460325403", 
"7089338530631756591", 
"15520654661378671735", 
"13041542794130379697"
]

Now indexOf() gives me -1 aka not found

userRoleIdsArray.indexOf(3191093315651213021);

OR

userRoleIdsArray.indexOf("3191093315651213021");

Gives :

-1

While

userRoleIdsArray[7]==3191093315651213021;

Gives :

true

What am I missing here? Is this not the way to use indexOf() ?

UPDATE >>> Stuff below was 'on-the-side' but turns out to be distracting from the above core question. The behaviour below is answered by @DaveCassel's comment.

btw on the created array acceptedRoleIds it is even more strange:

acceptedRoleIds.indexOf(spoId);

works

acceptedRoleIds.indexOf(3191093315651213021);

does not?

Could this large number error in javascript be relevant?

Community
  • 1
  • 1
Hugo Koopmans
  • 1,349
  • 1
  • 15
  • 27
  • 1
    Well, type `3191093315651213021` into the browser console and press enter and you'll see. – JJJ Dec 17 '15 at 14:09
  • 1
    Tried userRoleIdsArray.indexOf("3191093315651213021"); ? – Idos Dec 17 '15 at 14:09
  • 4
    That said, if the ids are strings, why are you trying to use integers to access them? – JJJ Dec 17 '15 at 14:10
  • @Idos I am afraid the question is more complex then you realize, this is not a plain javascript question... Your answer does NOT solve my problem... Your code works alright. But agiain my problem is that if I convert a ValueIterator (which I believe is ML specific) to an array and I use the indexOf() function in MarkLogic I have the above problem. – Hugo Koopmans Dec 18 '15 at 15:27

2 Answers2

3

You want to find a String, not a number. Use: userRoleIdsArray.indexOf("3191093315651213021");

This works:

var array = [
"1088529792688125909", 
"1452323661308702627", 
"10258509559147330558", 
"10161853410412530308", 
"6677433310138437512", 
"12773061729023600875", 
"7482704131174481508", 
"3191093315651213021",
"5126952842460325403", 
"7089338530631756591", 
"15520654661378671735", 
"13041542794130379697"
];
var n = array.indexOf("13041542794130379697");
document.write(n);

output: 11

Idos
  • 15,053
  • 14
  • 60
  • 75
  • @HugoKoopmans - Doesn't matter what MarkLogic is - a string in a string and an int is an int. When you are building your array, you are building an array of strings (there are quotation marks around them). When you are querying for the index, you are asking for an index in the array with an int of that value. There are no integer values in your array, so it returns -1. – Jesse Williams Dec 17 '15 at 14:24
  • As an added note - MarkLogic is a NoSQL DB. What sort of DB connection you are making is irrelevant to the .js code itself. The part you are asking about isn't part of the DB, it's part of the javascript. – Jesse Williams Dec 17 '15 at 14:25
  • @JesseWilliams I am afraid that is not true, I am working with serverside javascript build from ground up by MarkLogic, so there are (apperently) some issues with this particular implementation of javascript that we are talking about here... – Hugo Koopmans Dec 17 '15 at 15:46
  • 2
    @HugoKoopmans it is impossible for us to know and therefore useless to really ask about it. You might as well just say it's a *brand new* language called JavaHugo and its indexOf works differently than Javascripts'. So the answer is correct then. – Idos Dec 17 '15 at 17:42
  • 2
    @HugoKoopmans the JavaScript implementation is not built from the ground up by MarkLogic; rather, we integrated the V8 engine, which also powers Node.js and Chrome. @Idos' answer is correct -- the problem is searching for an integer in an array of strings. To prove it, paste the code in this answer into Query Console, replace the `document.write(n)` with just `n` to return the value, and run. – Dave Cassel Dec 17 '15 at 20:41
  • 2
    BTW, `userRoleIdsArray[7]==3191093315651213021;` returns `true` because of the double-equals, which does automatic type conversion. Run the same command with triple-equals (`userRoleIdsArray[7]===3191093315651213021;`) and you get `false`. – Dave Cassel Dec 17 '15 at 20:43
  • @idios I explicitly tagged this question to be MarkLogic related, not only a javascript issue. That is were tags are meant for right? – Hugo Koopmans Dec 18 '15 at 15:33
  • @DaveCassel so then my question is: why does `userRoleIdsArray.indexOf("3191093315651213021")` not work? – Hugo Koopmans Dec 18 '15 at 15:34
  • I started looking at this as an array-of-strings problem, for which Idos' answer was correct. Digging deeper, I see that the type for the items in the array is [Value](http://docs.marklogic.com/ValueIterator.toArray?q=toarray&v=8.0&api=true). The indexOf isn't working because it's comparing a string to a Value object. I'm checking into the correct way to do this. – Dave Cassel Dec 18 '15 at 16:17
0

The mismatch is that ValueIterator.toArray() returns an array of Values (Value[]). When you call .indexOf, you're passing in a string or an unsignedLong rather than a value. Because the types don't match, .indexOf() doesn't report a match.

You can solve the problem by iterating through the loop. Note that I use the '==' operator rather than '==='; the type conversion is needed.

// get roleIds from sec db for this user
var userRoleIds = xdmp.userRoles('my-user');
// map ValueIterator to array
var userRoleIdsArray = userRoleIds.toArray(); 

var target = 15520654661378671735;
var index = -1;

for (var i in userRoleIdsArray) {
  if (userRoleIdsArray[i] == target) {
    index = i;
  }
}
index
Dave Cassel
  • 8,352
  • 20
  • 38