Search code examples
javascriptstringiterable

Why am I getting an error saying that my string is not an iterable?


I have a group of small functions which work together to convert a given string from underscore_case to camelCase. Here is a snippet with my code:

function splitStr(str) {
  return str.split('_');
}

function checkStrPosZero(strArr, str) {
  return !strArr.indexOf(str);
}

function editStrIfFalse(zero, str) {
  if (zero) return str;
  let returnStr = '';
  for (const char of str)
    if (checkStrPosZero(str, char)) returnStr += char.toUpperCase();
    else returnStr += char;
  return returnStr;
}

function loopStrArrAndCamelify(str) {
  let returnStr = '';
  for (const char of splitStr(str))
    returnStr += editStrIfFalse(checkStrPosZero(splitStr(str), char));
  return returnStr;
}

console.log(loopStrArrAndCamelify('hello_world'));

For some reason, I get an error saying that the str variable isn't an iterable, which doesn't make sense, as str is a string. Very confused, so any help is appreciated.


Solution

  • You're missing the second argument to editStrIfFalse(). So str defaults to undefined, which is not iterable.

    function splitStr(str) {
      return str.split('_');
    }
    
    function checkStrPosZero(strArr, str) {
      return !strArr.indexOf(str);
    }
    
    function editStrIfFalse(zero, str) {
      if (zero) return str;
      let returnStr = '';
      for (const char of str)
        if (checkStrPosZero(str, char)) returnStr += char.toUpperCase();
        else returnStr += char;
      return returnStr;
    }
    
    function loopStrArrAndCamelify(str) {
      let returnStr = '';
      for (const char of splitStr(str))
        returnStr += editStrIfFalse(checkStrPosZero(splitStr(str), char), char);
      return returnStr;
    }
    
    console.log(loopStrArrAndCamelify('hello_world'));

    Note that your algorithm won't work if the first word is repeated later. strArr.indexOf(str) will return the index of the first match of str, not the current index of the iteration, which will be 0 when you're processing a repeat of the first word. So for example, if the input is hello_world_hello, the result will be helloWorldhello rather than helloWorldHello.

    Also, if the first letter of a word is repeated, you have the same problem -- it will convert all the repeats to uppercase. So hello_wow becomes helloWoW.

    If you're going to iterate, you should iterate over the indexes, not the values, then you can test if index == 0. But there's no need for most of the iteration. To convert a word to camelcase, just do:

    new_word = word[0].toUpperCase() + word.substring(1).toLowerCase();
    

    And when you're iterating over the words, use for (let index = 1; index < words.length; index++) to process just the words after the first.