JS Challenges -- spread + matchAll = TypeError

Link to exercise.

It’s a challenge that requests that we create a subLength() function that takes 2 parameters, a string and a single character. The function should search the string for the two occurrences of the character and return the length between them including the 2 characters. If there are less than 2 or more than 2 occurrences of the character the function should return 0.

Now, I’ve tried to do it a certain way that I found on MDN and I really liked, but I receive an error. I will try to do it in another way, so please don’t tell me another way to do it, I just would like to know why is this not accepted, and if it’s something I should worry about in the future when I work as a developer.

Having said so, this is what I tried:

/ Write function below
const subLength = (string, charact) => {
    const appears = [...string.matchAll(charact)];
    if (appears.length < 2 || appears.length > 2){
        return 0;
    } else if (appears.length === 2){
        return appears[1].index - appears[0].index + 1;
    } else {
        return 'There has been an error with the input!';
    }
};

console.log(subLength('Saturday', 'a')); // returns 6
console.log(subLength('summer', 'm')); // returns 2
console.log(subLength('digitize', 'i')); // returns 0
console.log(subLength('cheesecake', 'k')); // returns 0

And this is the error stack trace:

/home/ccuser/workspace/assessment-5f8754a6e91ae500128deb08/main.js:3
    const appears = [...string.matchAll(charact)];
                               ^

TypeError: string.matchAll(...)[Symbol.iterator] is not a function
    at subLength (/home/ccuser/workspace/assessment-5f8754a6e91ae500128deb08/main.js:3:32)
    at Object.<anonymous> (/home/ccuser/workspace/assessment-5f8754a6e91ae500128deb08/main.js:15:13)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:427:7)
    at startup (bootstrap_node.js:151:9)

Now, the interesting part is: both Studio Code (Node) and Browser Console (JS) accept this and throw the output expected. The problem is only making it work on CodeCademy. Why?

NOTES:
The error in the stack trace is a TypeError because of the iterator. Now, I reviewed the documentation in MDN and the compatibility of matchAll() should not be the problem since it’s been in Node (used in CodeCademy’s console emulation, right?) ever since 12.0, but Node is now in 15+, 14+ being the safer recommended.

I also checked the same documentation page this specific usage of a spread operator (available for Node since 5.0) but there is an example that is very similar. You can check in the matchAll() page linked above, just above the compatibility table and you’ll see.

Thus, once again, why does this error happen and why only in CodeCademy while it does not occur in browser console nor in Visual Studio Code?
Or even… can I untangle it (without using any other method to achieve this)?

Thanks in advance!

1 Like

Just for the record. I already found a possible (although probably not the most elegant, I know) way that CC will accept. But I would still love to know any actual developer’s input on this issue.

Challenge spoiler: My other way around :)
const subLength = (string, charact) => {
    const splitWord = string.split('');
    const appears = splitWord.filter(letter => letter === charact);
    if (appears.length < 2 || appears.length > 2){
        return 0;
    } else if (appears.length === 2){
        const first = string.indexOf(charact);
        const second = string.lastIndexOf(charact);
        return second - first + 1;
    } else {
        return 'There has been an error with the input!';
    }
};

Every project / lesson that we’ve had access to bash in the learning environment that I’ve checked the version of node installed revealed an ancient version. I can’t say it’s across the board for every course because perhaps in some of them they pull from a more updated repository of system images. but each one I’ve checked is very old.

$ node --version
v7.10.1
1 Like

Thank you for answering! :+1:

Well, already taught me a lesson there… I should have checked the version like that, instead of insisting with my idea. (EDIT: Although right now I am on this “Practice JavaScript” part where I tried your code to find out the version but it didn’t give me nothing but just an error. I’ll try it on others, though.)

But still, would you mind telling me if in a real-life work scenario (like, say, working for a dev team in a company), you would normally check the version or install a more updated version? Or is there any other more common way to do this?

The reason for this question is I would change my approach to these challenges from now on depending on this, so that I can go through my learning in a way similar to the one I’ll face later. (Just as an example, if you tell me that normally, you just check the node version and work for that version, then I will do just that in every challenge checking compatibility tables; however, else if you tell me that in most cases you install your node version in the company’s server, then I’ll probably do like I did on this one: when I see that my solution won’t work, I’ll keep it on my files but then find another solution for the older version… etc.)

I am not sure if my understanding has gotten there yet, though, like if you’re using JS for the front-end you wouldn’t use Node, no? I’m a little confused.

Thank you again!

The command I provided is for when you’re on a lesson or project that gives you access to bash. You’ll come across it and have lessons about it soon enough if you haven’t run into it before. It will look like this within the learning environment and they will provide instructions on how to interact with it.
image

If you wanted to get the version programmatically, you could use the process.versions property, which has been around since v0.2.0, so I can’t imagine you’d ever find an earlier version being used in the wild

const process = require('process');
console.log(process.versions.node);

As for a real-life work scenario to install a more updated version, that’s going to be highly dependent on a number of other factors, such as the company, the client, co-workers, server environment, compatibility with other packages, budget, etc.

Anything involving an existing product, especially in production, would likely require a bunch of testing in a staging environment and/or using automated testing tools in order to even think about upgrading the version. There would also need to be a compelling reason, such as security issues.

For a new project, you’ll likely find yourself using the latest LTS (long-term support) version of node, but even this may not be the case depending on client requirements.

If you end up consulting for a number of clients or working with a company handling multiple projects, you may even find yourself using Node Version Manager so you can change your node version on the fly on your development system, or perhaps using other tools such as Docker to make sure you have an environment that is as close to what it will run on as possible.

Those are just a few scenarios.

Of all the projects I’ve done on Codecademy, only the X-Press Publishing project had a version incompatibility issue. The newer version of node I had installed wasn’t compatible with the old version of sqlite3 it wanted to use. It was a quick fix by telling the project to use a newer version of sqlite that worked. I’m not sure that project even exists in the newer career paths, but the point is that you shouldn’t worry too much right now.

I suggest that when you run into scenarios where the learning environment isn’t accepting something you know should work, then double check the compatibility (or double check the test because some of them are extra picky). The experience you had with matchAll, although possibly frustrating or confusing, was still a good learning experience - both in successfully using an ECMAScript 2020 feature and rewriting it. When you’re working on a project on your machine, such as the one I mentioned above or the portfolio projects, then you control the versions.

The version of node will matter the most when you’re working on the back-end, but there are some cases when it matters for the front-end as well, even though ultimately the code will run in the browser and not in node. The tools you use to build the front-end could depend on node throughout the build process. For example, if you’re using React and decide to use the create-react-app, the recommended way of using it requires node version 8.10 or higher.

You’ll learn a lot more about all of this during your journey at Codecademy.

1 Like

Wow! Thank you so much for that answer. I mean, I really can’t thank you enough!

That has taught me a lot of really important and crucial things, gave me food for thought to research now and to come back to at a later point, and even let me with some new things I might use for life.

Really, thank you for your time on this and your incredibly helpful answer! :+1:

By the way, yeah, I just came at the point of that bash you’re showing me, and both worked as you told me. :tada:

1 Like