2

I have the following array, and would like to determine whether the a value is contained in the array using indexOf.

var testarray = ["RiskCCMismatch", "ContentVersion"]

var testresult = testarray.indexOf("RiskCCMismatch");

I receive the following error:

Jint.JintException: Object expected: indexOf

Is the function supported in SSJS for SFMC?

If not, how can I search within an array?

3 Answers 3

4

You can not get the array value directly without using array index number. you should pass the index number to determine whether the value is contained in the array using indexOf function. below is the working code

<script runat=server>
Platform.Load("core", "1");     
    var testarray = ["Exact Target","Salesforce Marketing Cloud"];  
    var testresult = testarray[0].indexOf("Target");    
    Write(testresult); 
</script>

Also, if Array is contain multiple value and need to check each index number dyamically so use FOR LOOP.

<script runat=server>
    Platform.Load("core", "1");
    var testarray = ["Exact Target","Salesforce Marketing Cloud"];
    for(var i=0; testarray.length>i; i++){
        var testresult = testarray[i].indexOf("Target");
            if(testresult>=0){
                Write('True');
            }
        }
</script>
1
  • 1
    This is VERY different than doing indexOf in the whole array. Sep 7, 2017 at 11:11
10

The part of Marketing Cloud that handles SSJS is a derelict .NET app and thus the version of Jint, a C# JavaScript interpreter, used to run your script is an incomplete implementation of the ECMAScript 3.0 spec. Array's iterative methods like indexOf, map, and reduce didn't appear until ES5. If you want to use them, you'll need to polyfill. For example, here's the Array.prototype.indexOf polyfill from MDN, modified so Marketing Cloud's JavaScript interpreter won't panic:

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = (function (Obj, max, min) {
    'use strict'
    return function indexOf (member, fromIndex) {
      if (this === null || this === undefined) {
        throw TypeError('Array.prototype.indexOf called on null or undefined')
      }

      var that = new Obj(this)
      var len = that.length
      var i = min(fromIndex || 0, len)

      if (i < 0) {
        i = max(0, len + i)
      } else if (i >= len) {
        return -1
      }

      if (member === undefined) {
        for (; i !== len; ++i) {
          if (that[i] === undefined && i in that) {
            return i // undefined
          }
        }
      } else if (member !== member) {
        for (; i !== len; ++i) {
          if (that[i] !== that[i]) {
            return i // NaN
          }
        }
      } else {
        for (; i !== len; ++i) {
          if (that[i] === member) {
            return i // all else
          }
        }
      }

      return -1 // if the value was not found, then return -1
    }
  }(Object, Math.max, Math.min))
}

Here are some general tips on tweaking polyfills for use in SSJS:

  • Always use new keyword with constructors, even those for which it's commonly omitted, like Object(), Array(), and Error(). It is safe to use your discretion for the Boolean() and String() constructors.
  • instanceof is seriously broken. Find an alternative check.
  • There is no __proto__, only Zuul prototype: Get it with <BuiltIn>.prototype for built-ins and objects with type "clr" or "clrmethodinfo", and Object.getPrototypeOf(obj) for everything else; set it like obj.prototype = proto.
  • Bitwise operators are buggy because:
    • Operands are cast from JavaScript's double precision numbers to UInt64 in C# prior to applying the operation. This can cause the engine to throw integer overflow errors when Jint tries to pack the numbers back into an UInt32. I'm not certain under which conditions Jint will cast to Float64 or UInt32.
    • In most JavaScript engines, ~8 (1000) yields -9 (-1001); as executed by Jint, operations affect all 64 bits of a UInt64, not just the shortest array of bits necessary to represent the number; thus, ~8 (1000) becomes 18446744073709551607 (1111111111111111111111111111111111111111111111111111111111110111). As Float64s are very holey as N gets very large or very small, the JavaScript value becomes 18446744073709600000 after coercion and rounding.
  • Object is the constructor of all constructors, not Function, and functions do not inherit from Function.prototype. You'll find yourself in a bind trying to implement Function.prototype.bind.
1
  • does every Polyfill I found on MDN work on ssjs ? I have copy paste, map and others but doesnt work, any idea ?
    – AshBringer
    Jul 2, 2019 at 13:22
2

As @palash explained, you can't get the array value directly in SSJS without using array index number, but no one is stopping you from flattening the array to a string :-)

<script runat=server>
Platform.Load("core", "1"); 
  var testarray = ["Exact Target","Salesforce Marketing Cloud"];
  var testarrayStr = testarray.toString();
  var testresult = testarrayStr.indexOf("Target");    
  Platform.Response.Write('testresult: ' + testresult); // 6
</script> 
1
  • 1
    Nice, thanks Eliot!
    – zuzannamj
    Sep 29, 2020 at 11:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .