tutorial

You can actually stop a “forEach” loop in JavaScript – in 5 ways

Can you break out of a “forEach” loop in JavaScript?

It’s an amazing question to challenge just how well you really know JavaScript.

Because we’re not talking for loops — or this would have been ridiculously easy: you just break:

But you wouldn’t dare do this with forEach, or disaster happens:

What about return… mhmm.

What do you think is going to happen here:

return should easily end the loop at 5 and take us to the outer log right?

Wrong:

Remember: forEach takes a callback and calls it FOR EACH item in the array.

JavaScript
// Something like this: Array.prototype.forEach = function (callback, thisCtx) { const length = this.length; let i = 0; while (i < length) { // 👇 callback run once and only once callback.call(thisCtx, this[i], i, this); i++; } };

So return only ends the current callback call and iteration; doing absolutely nothing to stop the overall loop.

It’s like here; trying to end func2() from func1() — obviously not going to work:

5 terrible ways to stop a forEach loop

1. Throw an exception

You can stop any forEach loop by throwing an exception:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; try { nums.forEach((num) => { if (num === 5) { throw new Error('just to stop a loop?'); } console.log(num); }); } catch { console.log('finally stopped!'); }

Of course we’re just having fun here — this would be horrible to see in real-world code. We only create exceptions for problems, not planned code like this.

2. process.exit()

This one is extreme:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; nums.forEach((num) => { if (num === 5) { process.exit(0); } console.log(num); });

Not only are you ending the loop, you’re ending the entire program!

You won’t even get to the console.log() here:

3. Array some()

This is bad.

It works and some people recommended it for this; but this lowers readability as it’s clearly not what it’s meant for.

This is what it’s meant for:

JavaScript
const nums = ['bc', 'bz', 'ab', 'bd']; const hasStartingA = nums.some((num) => num.startsWith('a') ); const hasStartingP = nums.some((num) => num.startsWith('p') ); console.log(hasStartingA); // true console.log(hasStartingP); // false

4. Set array length to 0

But here’s something even more daring: Setting the length of the array to 0!

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; function myFunc() { nums.forEach((num) => { if (num === 5) { nums.length = 0; } console.log(num); }); console.log('it worked!'); console.log(nums); } myFunc();

Setting the array’s length completely destroys and resets it — EMPTY array:

5. Use Array splice()

Things get even weirder when you use Array splice() to stop the foreach loop, deleting slashing away elements mid-way!

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; function myFunc() { nums.forEach((num, i) => { if (num === 5) { nums.splice(i + 1, nums.length - i); } console.log(num); }); console.log('spliced away!'); console.log(nums); } myFunc();

3 great ways to stop a loop

1. Do you really need to break?

Instead of using the terrible methods above to stop a forEach loop…

Why not refactor your code so you don’t need to break at all?

So, instead of this:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; try { nums.forEach((num) => { if (num === 5) { // ❌ break at 5 throw new Error('just to stop a loop?'); } console.log(num); }); } catch { console.log('finally stopped!'); }

We could have simply done this:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; nums.forEach((num) => { if (num < 5) { // ignore 5 or more console.log(num); } }); console.log('no need to break!');

2. Use for of

But if you really want to jump out of the loop early then you’re much better of with the for..of loop:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; try { for (const num of nums) { if (num === 5) { break; // 👈 break works } console.log(num); } } catch { console.log('finally stopped!'); }

3. Use traditional for

Or with the traditional for loop, for more fine-grained control:

JavaScript
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; try { for (let i = 0; i < nums.length; i += 2) { // 👈 jump by 2 const num = nums[i]; if (num === 5) { break; } console.log(num); } } catch { console.log('finally stopped!'); }

Final thoughts

So there are ways to “break” from a forEach loop, but they’re pretty messy and insane.

Instead try refactoring the code to avoid needing to break in the first place. Or switch to for and for..of for a cleaner, readable approach.

Stop using nested ifs: Do this instead

Typical use case for nested ifs: you want to perform all sorts of checks on some data to make sure it’s valid before finally doing something useful with it.

Don’t do this! 👇

JavaScript
function sendMoney(account, amount) { if (account.balance > amount) { if (amount > 0) { if (account.sender === 'user-token') { account.balance -= amount; console.log('Transfer completed'); } else { console.log('Forbidden user'); } } else { console.log('Invalid transfer amount'); } } else { console.log('Insufficient funds'); } }

There’s a better way:

JavaScript
function sendMoney(account, amount) { if (account.balance < amount) { console.log('Insufficient funds'); return; } if (amount <= 0) { console.log('Invalid transfer amount'); return; } if (account.sender !== 'user-token') { console.log('Forbidden user'); return; } account.balance -= amount; console.log('Transfer completed'); }

See how much cleaner it is? Instead of nesting ifs, we have multiple if statements that do a check and return immediately if the condition wasn’t met. In this pattern, we can call each of the if statements a guard clause.

If you do a lot of Node.js, you’ve probably seen this flow in Express middleware:

JavaScript
function authMiddleware(req, res, next) { const authToken = req.headers.authorization; if (!authToken) { return res.status(401).json({ error: 'Unauthorized' }); } if (authToken !== 'secret-token') { return res.status(401).json({ error: 'Invalid token' }); } if (req.query.admin === 'true') { req.isAdmin = true; } next(); }

It’s much better than this, right? :

JavaScript
function authMiddleware(req, res, next) => { const authToken = req.headers.authorization; if (authToken) { if (authToken === 'secret-token') { if (req.query.admin === 'true') { req.isAdmin = true; } return next(); } else { return res.status(401).json({ error: 'Invalid token' }); } } else { return res.status(401).json({ error: 'Unauthorized' }); } };

You never go beyond one level of nesting. We can avoid the mess that we see in callback hell.

How to convert nested ifs to guard clauses

The logic for this for doing this is simple:

1. Find the innermost/success if

Here we can clearly see it’s the cond3 if. After this, if we don’t do any more checks and take the action we’ve always wanted to take.

JavaScript
function func(cond1, cond2, cond3) { if (cond1) { if (cond2) { if (cond3) { console.log('PASSED!'); console.log('taking success action...'); } else { console.log('failed condition 3'); } } else { console.log('failed condition 2'); } } else { console.log('failed condition 1'); } }

2. Invert the outermost if and return

Negate the if condition to put the else statements’ body in there and add a return after.

Delete the else braces (keep the body, it still contains the formerly nested ifs, and move the closing if brace to just after the return.

So:

JavaScript
function func(cond1, cond2, cond3) { if (!cond1) { // 👈 inverted if condition // 👇 body of former else clause console.log('failed condition 1'); return; // 👈 exit on fail } // 👇 remaining nested ifs to convert to guard clauses if (cond2) { if (cond3) { console.log('PASSED!'); console.log('taking success action...'); } else { console.log('failed condition 3'); } } else { console.log('failed condition 2'); } }

3. Do the same for each nested if until you reach the success if

And then:

JavaScript
function func(cond1, cond2, cond3) { if (!cond1) { console.log('failed condition 1'); return; } if (!cond2) { console.log('failed condition 2'); return; } // 👇 remaining nested ifs to convert if (cond3) { console.log('PASSED!'); console.log('taking success action...'); } else { console.log('failed condition 3'); } }

And finally:

JavaScript
function func(cond1, cond2, cond3) { if (!cond1) { console.log('failed condition 1'); return; } if (!cond2) { console.log('failed condition 2'); return; } if (!cond3) { console.log('failed condition 3'); return; } console.log('PASSED!'); console.log('taking success action...'); }

I use the JavaScript Booster extension to make inverting if statements in VS Code much easier.

Here we only had to put the cursor in the if keyword and activate the Show Code Actions command (Ctrl + . by default).

Check out this article for an awesome list of VSCode extensions you should definitely install alongside with JavaScript Booster.

Tip: Split guard clauses into multiple functions and always avoid if/else

What if we want to do something other after checking the data in an if/else? For instance:

JavaScript
function func(cond1, cond2) { if (cond1) { if (cond2) { console.log('PASSED!'); console.log('taking success action...'); } else { console.log('failed condition 2'); } console.log('after cond2 check'); } else { console.log('failed condition 1'); } console.log('after cond1 check'); }

In this function regardless of cond1‘s value, the 'after cond1 check' the line will still print. Similar thing for the cond2 value if cond1 is true.

In this case, it takes a bit more work to use guard clauses:

If we try to use guard clauses, we’ll end up repeating the lines that come after the if/else checks:

JavaScript
function func(cond1, cond2) { if (!cond1) { console.log('failed condition 1'); console.log('after cond1 check'); return; } if (!cond2) { console.log('failed condition 2'); console.log('after cond2 check'); console.log('after cond1 check'); return; } console.log('PASSED!'); console.log('taking success action...'); console.log('after cond2 check'); console.log('after cond1 check'); } func(true);

Because the lines must be printed, we print them in the guard clause before returning. And then, we print it in all(!) the following guard clauses. And once again, in the main function body if all the guard clauses were passed.

So what can we do about this? How can we use guard clauses and still stick to the DRY principle?

Well, we split the logic into multiple functions:

JavaScript
function func(cond1, cond2) { checkCond1(cond1, cond2); console.log('after cond1 check'); } function checkCond1(cond1, cond2) { if (!cond1) { console.log('failed condition 1'); return; } checkCond2(cond2); console.log('after cond2 check'); } function checkCond2(cond2) { if (!cond2) { console.log('failed condition 2'); return; } console.log('PASSED!'); console.log('taking success action...'); }

Let’s apply this to the Express middleware we saw earlier:

JavaScript
function authMiddleware(req, res, next) { checkAuthValidTokenAdmin(req, res, next); } function checkAuthValidTokenAdmin(req, res, next) { const authToken = req.headers.authorization; if (!authToken) { return res.status(401).json({ error: 'Unauthorized' }); } checkValidTokenAdmin(req, res, next); } function checkValidTokenAdmin(req, res, next) { const authToken = req.headers.authorization; if (authToken !== 'secret-token') { return res.status(401).json({ error: 'Invalid token' }); } checkAdmin(req, res, next); } function checkAdmin(req, res, next) { if (req.query.admin === 'true') { req.isAdmin = true; } next(); }

In a way, we’ve replaced the if/else statements with a chain of responsibility pattern. Of course, this might be an overkill for simple logic like a basic Express request middleware, but the advantage here is that it delegates each additional check to a separate function, separating responsibilities and preventing excess nesting.

Key takeaways

Using nested ifs in code often leads to complex and hard-to-maintain code; Instead, we can use guard clauses to make our code more readable and linear.

We can apply guard clauses to different scenarios and split them into multiple functions to avoid repetition and split responsibilities. By adopting this pattern, we end up writing cleaner and more maintainable code.

The 5 most transformative JavaScript features from ES14

JavaScript has come a long way in the past 10 years with brand new feature upgrades in each one.

Still remember when we created classes like this?

JavaScript
function Car(make, model) { this.make = make; this.model = model; } // And had to join strings like this Car.prototype.drive = function() { console.log("Vroom! This " + this.make + " " + this.model + " is driving!"); };

Yeah, a lot has changed!

Let’s take a look at the 5 most significant features that arrived in ES14 (2023); and see the ones you missed.

1. toSorted()

Sweet syntactic sugar.

ES14’s toSorted() method made it easier to sort an array and return a copy without mutation.

Instead of this:

JavaScript
const nums = [5, 2, 6, 3, 1, 7, 4]; const sorted = clone.sort(); console.log(sorted); // [1, 2, 3, 4, 5, 6, 7] // ❌❌ Mutated console.log(nums); // [1, 2, 3, 4, 5, 6, 7]

We now got to do this ✅:

JavaScript
const nums = [5, 2, 6, 3, 1, 7, 4]; // ✅ toSorted() prevents mutation const sorted = nums.toSorted(); console.log(sorted); // [1, 2, 3, 4, 5, 6, 7] console.log(nums); // [5, 2, 6, 3, 1, 7, 4]

toSorted() takes a callback for controlling sorting behavior – ascending or descending, alphabetical or numeric. Just like sort().

2. Array find from last

Searching from the first item isn’t always ideal:

JavaScript
const tasks = [ { date: '2017-03-05', name: '👟run a 5k' }, { date: '2017-03-04', name: '🏋️lift 100kg' }, { date: '2017-03-04', name: '🎶write a song' }, // 10 million records... { date: '2024-04-24', name: '🛏️finally sleep on time' }, { date: '2024-04-24', name: '📝1h writing with no breaks' }, ]; const found = tasks.find((item) => item.date === '2024-03-25'); const foundIndex = tasks.findIndex((item) => item.date === '2024-03-25'); console.log(found); // { value: '2024-03-25', name: 'do 1000 pushups' } console.log(foundIndex); // 9,874,910

You can easily see that it’ll be much faster for me to search our gigantic list from the end instead of start.

JavaScript
const tasks = [ { date: '2017-03-05', name: 'run a 5k' }, { date: '2017-03-04', name: 'lift 100kg' }, { date: '2017-03-04', name: 'write a song' }, // 10 million records... { date: '2024-04-24', name: 'finally sleep on time' }, { date: '2024-04-24', name: '1h writing with no breaks' }, ]; // ✅ Much faster const found = tasks.findLast((item) => item.date === '2024-03-25'); const foundIndex = tasks.findLastIndex((item) => item.date === '2024-03-25'); console.log(found); // { value: '2024-03-25', name: 'do 1000 pushups' } console.log(foundIndex); // 9,874,910

And they’re also times you MUST search from the end for your program work.

Like we want to find the last even number in a list of numbers, find and findIndex will be incredibly off.

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; // ❌ gives 14, instead of 10 const lastEven = nums.find((value) => value % 2 === 0); // ❌ gives 1, instead of 4 const lastEvenIndex = nums.findIndex((value) => value % 2 === 0); console.log(lastEven); // 14 console.log(lastEvenIndex); // 1

And calling reverse() won’t work either, even as slow as it would be:

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; // ❌ Copying the entire array with the spread syntax before // calling reverse() const reversed = [...nums].reverse(); // correctly gives 10 const lastEven = reversed.find((value) => value % 2 === 0); // ❌ gives 1, instead of 4 const reversedIndex = reversed.findIndex((value) => value % 2 === 0); // Need to re-calculate to get original index const lastEvenIndex = reversed.length - 1 - reversedIndex; console.log(lastEven); // 10 console.log(reversedIndex); // 1 console.log(lastEvenIndex); // 4

So in cases like where the findLast() and findLastIndex() methods come in handy.

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; // ✅ Search from end const lastEven = nums.findLast((num) => num % 2 === 0); // ✅ Maintain proper indexes const lastEvenIndex = nums.findLastIndex((num) => num % 2 === 0); console.log(lastEven); // 10 console.log(lastEvenIndex); // 4

This code is shorter and more readable. Most importantly, it produces the correct result.

3. toReversed()

Another new Array method to promote immutability and functional programming.

Before – with reverse() ❌:

JavaScript
const arr = [5, 4, 3, 2, 1]; const reversed = arr.reverse(); console.log(reversed); // [1, 2, 3, 4, 5] // ❌ Original modified console.log(arr); // [1, 2, 3, 4, 5]

Now – with toReversed() ✅:

JavaScript
const arr = [5, 4, 3, 2, 1]; const reversed = arr.toReversed(); console.log(reversed); // [1, 2, 3, 4, 5] // ✅ No modification console.log(arr); // [5, 4, 3, 2, 1]

I find these immutable methods awesome for constantly chaining methods over and over without worrying about the original variables:

JavaScript
// ✅ Results are independent of each other const nums = [5, 2, 6, 3, 1, 7, 4]; const result = nums .toSorted() .toReversed() .map((n) => n * 2) .join(); console.log(result); // 14,12,10,8,6,4,2 const result2 = nums .map((n) => 1 / n) .toSorted() .map((n) => n.toFixed(2)) .toReversed(); console.log(result2); // [ '1.00', '0.50', '0.33', '0.25', // '0.20', '0.17', '0.14' ]

4. toSpliced()

Lovers of functional programming will no doubt be pleased with all these new Array methods.

This is the immutable counterpart of .splice():

JavaScript
const colors = ['red🔴', 'purple🟣', 'orange🟠', 'yellow🟡']; // Remove 2 items from index 1 and replace with 2 new items const spliced = colors.toSpliced(1, 2, 'blue🔵', 'green🟢'); console.log(spliced); // [ 'red🔴', 'blue🔵', 'green🟢', 'yellow🟡' ] // Original not modified console.log(colors); // ['red🔴', 'purple🟣', 'orange🟠', 'yellow🟡'];

5. Array with() method

with() is our way of quickly change an array element with no mutation whatsoever.

Instead of this usual way:

JavaScript
const arr = [5, 4, 7, 2, 1] // Mutates array to change element arr[2] = 3; console.log(arr); // [5, 4, 3, 2, 1]

ES14 now let us do this:

JavaScript
const arr = [5, 4, 7, 2, 1]; const replaced = arr.with(2, 3); console.log(replaced); // [5, 4, 3, 2, 1] // Original not modified console.log(arr); // [5, 4, 7, 2, 1]

Final thoughts

They were other features but ES14 was all about easier functional programming and built-in immutability.

With the rise of React we’ve seen declarative JavaScript explode in popularity; it’s only natural that more of them come baked into the language as sweet syntactic sugar.

3 ways to show line breaks in HTML without ever using br

Of course <br/> is what we all grew up with from our HTML beginnings, but there’s more.

Like… CSS white-space: pre-wrap:

HTML
<div id="box"> Coding is cognitively demanding, mentally stimulating, emotionally rewarding, beauty, unity power </div>
CSS
#box { background-color: #e0e0e0; width: 250px; font-family: Arial; white-space: pre-wrap; }

Without pre-wrap:

pre-wrap preserves line breaks and sequences of whitespace in the element’s text.

So the 4 spaces between the words in the first line are shown in the output along with the line break.

Even the space used for text indentation is also shown in the output, adding extra left padding to the container.

JS too

pre-wrap also acknowledges the \n character when set from JavaScript; with innerText or innerHTML:

JavaScript
const box = document.getElementById('box'); box.innerText = 'Coding is \n logic, art, growth, \n creation';

Without pre-wrap:

pre

pre works a lot like pre-wrap but no more auto wrapping:

For example:

HTML
<div id="box"> JavaScript at Coding Beauty HTML at Coding Beauty CSS at Coding Beauty </div>
CSS
#box { white-space: pre; background-color: #e0e0e0; width: 250px; font-family: Arial; }

If pre was pre-wrap in this example:

The behavior with pre is the same when you set the innerHTML or innerText property of the element to a string using JavaScript.

Newlines only

white-space:pre-line: Ignore extra spaces but show line breaks:

HTML
<div id="box"> Coding is growth unity power beauty </div>
CSS
#box { background-color: #e0e0e0; width: 250px; font-family: Arial; white-space: pre-line }

pre-line -> pre-wrap:

Like the previous two possible white-space values, pre-line works in the same way when you set the innerHTML or innerText property of the element to a string using JavaScript.

Fix “Cannot read property ‘map’ of undefined” in React

Are you currently experiencing the “Cannot read property ‘map’ of undefined” error in your React app?

The "Cannot read properties of undefined (reading 'map')" error in the browser console.
The “Cannot read properties of undefined (reading ‘map’)” error in the browser console.

This error happens when you call the map() method on a variable that was meant to be an array, but is actually undefined. The variable could be a property or state variable.

For example:

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { // ❌ `books` is `undefined` const [books, setBooks] = useState(undefined); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); }, []); return ( <div> {books.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } export default App;

We’ll use this example to learn some easy ways to quickly fix this error in React.

Fix: Use optional chaining operator (?.)

To fix the “Cannot use property ‘map’ of undefined” error in React.js, use the optional chaining operator (?.) to access the map() method:

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { const [books, setBooks] = useState(undefined); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); }, []); return ( <div> {/* ✅ Fix with optional chaining (?.) */} {books?.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } export default App;

The optional chaining operator lets us safely access a property on a value that may be undefined or null. If it is, the operator will return undefined immediately and prevent the property access or method call.

JavaScript
const auth = undefined; console.log(auth); // undefined // ✅ No error console.log(auth?.user?.name); // undefined

Fix: Use AND operator (&&)

You can also use the && operator to check if the value is undefined before access it in the JSX:

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { const [books, setBooks] = useState(undefined); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); }, []); return ( <div> {/* ✅ Fix with AND operator (&&) */} {books && books.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } export default App;

Here’s what a chain of && does: it returns the right-most variable if all the variables are truthy. Otherwise, it returns the left-most falsy variable:

JavaScript
console.log(undefined && 0 && []); // undefined console.log(10 && null && 'coding'); // null console.log(10 && [5, 7] && 'coding'); // coding

Note: These are the falsy values in JavaScript: undefined, null, 0, false, '' (empty string), and NaN. Every other value is truthy.

Fix: Initialize state variable to empty array

The applies when the array value is a state variable like in our example.

We set the state to an empty array ([]) at the point where it’s created, so it never becomes undefined, preventing the “Cannot read property ‘map’ of undefined” error.

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { // ✅ `books` starts out as an array, not `undefined` const [books, setBooks] = useState([]); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); }, []); return ( <div> {books.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } export default App;

Fix: Create a loading state when fetching data

Apart from initializing the state to an empty array you can also display a loading indicator when performing network request, or some other time-consuming operation:

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { const [books, setBooks] = useState(undefined); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); // ✅ Lists books with .map() after loading completes setLoading(false); }, []); let listEl; if (loading) { listEl = <div>Loading...</div>; } else { listEl = ( <div> {books.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } return <div>{listEl}</div> } export default App;

Most web user interfaces have at least three states – loading, error, and success state, and we could be better off representing all three of them:

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; // TypeScript // type UIState = 'loading' | 'error' | 'success'; function App() { const [books, setBooks] = useState(undefined); const [state, setState] = useState('loading'); // TypeScript // const [state, setState] = useState<UIState>('loading'); useEffect(() => { try { (async () => { setBooks(await fetchBooks()); setState('success'); })(); // ✅ Lists books with .map() after loading completes } catch (err) { setState('error'); } }, []); const listViewMap = { loading: <div>Loading...</div>, error: <div>An error occured, try again later.</div>, success: ( <div> {books.map((book) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ), }; const listEl = listViewMap[state]; return <div>{listEl}</div>; } export default App;

Fix: Check the value assigned to the array

Maybe you initialized the array properly and did everything else right, but you set it to undefined at some point in the code.

If the array is to be filled with API data, are you sure you’re making the network request properly.

For example, if our fetchBooks() function was defined like below, it will cause a “Cannot read property ‘map’ of undefined” error when there’s a network error on the user’s device.

JavaScript
export async function fetchBooks() { const res = fetch('https://api.example/books', { headers: { 'Content-Type': 'application/json', Accept: 'application/json', }, }); // ❌ Will return `undefined` if status code is not 200 return res.status === 200 ? (await res).json() : undefined; }

Make sure you handle all the edge cases in your app.

Fix: Check your variable names

Sometimes the error happens due to a error in your variable names.

JavaScript
import { useState, useEffect } from 'react'; import { fetchBooks } from './books'; function App() { const [books, setBooks] = useState([]); useEffect(() => { (async () => { setBooks(await fetchBooks()); })(); }, []); return ( <div> {books.map((books) => ( <div key={book.id}> <h2>Title: {book.title}</h2> <p>Author: {book.author}</p> </div> ))} </div> ); } export default App;

Here we mistakenly create a books variable in the map() callback but we use book identifier in the JSX, which is what we actually intended. The causes the unfortunate error, aside from the fact that it shadows the outer books state variable.

[SOLVED] Cannot use import statement outside a module in JavaScript

Are you currently experiencing the “Cannot use import statement outside a module” error in JavaScript?

The "Cannot use import statement outside a module" error in a browser console.
The “Cannot use import statement outside a module” error in a browser console.

This is a well-known error that happens when you use the import keyword to load a file or package that is not a module.

Let’s learn how to easily fix this error in Node.js or the browser.

Fix “Cannot use import statement outside a module” in browser

Fix: Set type="module" in <script> tag

The “Cannot use import statement outside a module” error happens in a browser when you import a file that is a module without indicating this in the <script> tag.

index.html
<!DOCTYPE html> <html> <head> <title>Coding Beauty</title> <link rel="icon" href="favicon.ico" /> </head> <body> A site to make you enjoy coding <!-- ❌ SyntaxError: Cannot use import statement outside a module --> <script src="index.js"></script> </body> </html>

To fix it, add type="module" to the <script> tag.

index.html
<!DOCTYPE html> <html> <head> <title>Coding Beauty</title> <link rel="icon" href="favicon.ico" /> </head> <body> A site to make you enjoy coding <!-- ✅ Loads script successfully --> <script type="module" src="index.js"></script> </body> </html>

Fix “Cannot use import statement outside a module” in Node.js

The “Cannot use import statement outside a module” error happens when you use the import keyword in a Node.js project that doesn’t use the ES module import format.

index.js
// ❌ SyntaxError: Cannot use import statement outside a module import axios from 'axios'; const { data } = ( await axios.post('https://api.example.com/hi', { hello: 'world', }) ).data; console.log(data);

Fix: Set type: "module" in package.json

To fix the error in Node.js, set the package.json type field to “module”.

package.json
{ // ... "type": "module", // ... }

Now you can use the import statement with no errors:

index.js
// ✅ Imports successfully import axios from 'axios'; const { data } = ( await axios.post('https://api.example.com/hi', { hello: 'world', }) ).data; console.log(data);

If there’s no package.json in your project, you can initialize one with the npm init -y command.

Shell
npm init -y

The -y flags creates the package.json with all the default options – no user prompts for the fields.

Fix: Use require instead of import

Alternatively, you can fix the “Cannot use import statement outside a module” error in JavaScript by using the require() function in place of the import syntax:

index.js
// ✅ Works - require instead of import const axios = require('axios'); const { data } = ( await axios.post('https://api.example.com/hi', { hello: 'world', }) ).data; console.log(data);

But require() only works on the older, Node-specific CommonJS module system, and these days more and more modules are dropping support for CommonJS in favor of ES6+ modules.

For example, if you use require() for modules like got, node-fetch, and chalk, you’ll get the “require of ES modules is not supported error”.

index.js
// ❌ [ERR_REQUIRE_ESM]: require() of ES Module not supported const chalk = require('chalk'; console.log(chalk.blue('Coding Beauty'));

If you can’t switch to an ES module environment, you can fix this by dynamically importing the module with the async import() function. For example:

index.js
// CommonJS module // ✅ Imports successfully const chalk = (await import('chalk')).default; console.log(chalk.blue('Coding Beauty'));

Or, you can downgrade to an earlier version of the package that supported CommonJS and require().

Shell
npm install chalk@4 # Yarn yarn add got@4

Here are the versions you should install for various well-known NPM packages to avoid this ERR_REQUIRE_ESM error:

Package versions for downgrading to fix the "Cannot use import statement outside a module" error in JavaScript.

Fix “Cannot use import statement outside a module” in TypeScript

If the module field in tsconfig.json is set to commonjs, any import statement in the TypeScript source will change to require() calls after the compilation and potentially cause this error.

tsconfig.json
{ //... "type": "module" }

Prevent this by setting module to esnext or nodenext

tsconfig.json
{ "type": "module" }

nodenext indicates to the TypeScript compiler that the project can emit files in either ESM or CommonJS format.

[SOLVED] “auth/unauthorized domain” error in Firebase Auth

In this article, we’re going to learn how to easily fix the “auth/unauthorized domain” error which happens in the Firebase Authentication Web SDK.

What causes “auth/unauthorized domain” error in Firebase?

The Firebase “domain is not authorized” error happens when you try to use an API from Firebase Auth in a domain that is not authorized by Firebase.

It may occur in the FirebaseUI, or in your browser console.

The “auth/unauthorized” Firebase error occurring in FirebaseUI.

How to fix “auth/unauthorized domain” error in Firebase

To fix the “Domain not authorized” error in Firebase Auth, go to the Firebase Authentication Authorized domains settings for your project, using this link: https://console.firebase.google.com/project/_/authentication/settings.

Or by following these steps from the Firebase Console for your project in this image:

An image with steps to go to the Firebase Authentication Authorized domains settings page.

Enter the new domain in the dialog that shows after clicking Add domain:

Enter the new domain to register it as an authorized domain in Firebase Authentication.

How to get URL query string parameters in Next.js

Query parameters are used to pass data from the URL to the web server or browser. They are essential for customizing user experiences, filtering data, and tracking user actions.

Displaying the URL query parameters in a Next.js app.

Let’s learn how to easily get the query string parameters from a URL in a Next.js app.

In this article

Get URL query params in Next.js App Router client component

To get the URL query string parameters in the Next.js app directory, use the useSearchParams() hook from next/navigation.

app/amazing-url/page.tsx
'use client'; import { useSearchParams } from 'next/navigation'; export default function Home() { const searchParams = useSearchParams(); const query = searchParams.get('q'); return ( <> Welcome to Coding Beauty <br /> <br /> Your query: <b>{query}</b> </> ); }

We need ‘use client’ to use useSearchParams()

Notice the 'use client' statement at the top.

It’s there because all components in the new app directory are server components by default, so we can’t use any client-side specific functionality like hooks and animations.

We’ll get an error if we try to do anything interactive with useSearchParams or other hooks like useEffect, because it’s a server environment.

Get URL query params in Next.js Pages Router component

To get the URL query string parameters in pages directory component, use the query property of the useRouter() hook, which comes from the next/router module:

pages/coding-tips.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); const greeting = router.query.greeting; return ( <> <Head> <title>Coding Tips | Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.icon" /> </Head> <main> <h2>{greeting}</h2> <p>Appreciate the beauty of coding</p> </main> </> ); }

Get URL query params in Next.js middleware

To get the URL query string parameters in Next.js App or Pages Router middleware, use the request.nextUrl.searchParams property:

middleware.ts
import { NextResponse } from 'next/server'; import { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const continueUrl = request.nextUrl.searchParams.get('continue')!; return NextResponse.redirect(continueUrl); }

Get URL query params in Next.js server component

To get the URL query params in a server component, se the URL as a header in middleware, then parse this URL in the server component to get the query string and parameters:

middleware.ts
import { NextResponse } from 'next/server'; import { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const reqHeaders = new Headers(request.headers); // toLowerCase() to avoid 404 due to Next.js case-sensitivity const url = request.url.toLowerCase(); reqHeaders.set('x-url', url); return NextResponse.next({ request: { headers: reqHeaders, }, }); }
app/search/page.tsx
import { headers } from 'next/headers'; export default function Page() { const headerList = headers(); const url = headerList.get('x-url')!; const query = new URL(url).searchParams.get('q'); return ( <> <h2>Welcome to Coding Beauty.</h2> <p>Your query: {query}</p> </> ); }

Get URL query params in getServerSideProps()

To get the URL query string params in the Pages Router getServerSideProps() function, use the context.query property:

pages/random-lyrics.tsx
export async function getServerSideProps(context) { const { songId } = context.query; const res = await fetch(`https://api.example.com/lyrics?songId=${songId}`); const lyrics = await res.json(); return { props: { lyrics, }, }; } export default function LyricsPage({ lyrics }) { const { song, content } = lyrics; return ( <div> {song} lyrics<div>{content}</div> </div> ); }

Get URL query params in Next.js Pages Router API

To get the URL query string parameters in an API in the pages directory, use the request.query property:

pages/api/stock-prices.tsx
import type { NextApiRequest, NextApiResponse } from 'next'; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const { name } = req.query; const stockRes = await fetch(`api.example.com/stock-prices?name=${name}`); const stockData = await stockRes.json(); res.status(200).json({ stockData }); }

Get URL query params in Next.js App Router API

To get the URL query string params in an API in the Next.js 13 app directory, use the request.nextUrl.searchParams property:

app/api/forecast/route.ts
import { NextRequest, NextResponse } from 'next/server'; const data = { 'new-york': { summary: 'sunny' } // ... } export async function GET(req: NextRequest) { const location = req.nextUrl.searchParams.get('location'); const weatherData = data[location]; return NextResponse.json({ weatherData }); }

[SOLVED] Could not find an option named “no-sound-null-safety” in Flutter

Are you experiencing the “Could not find an option named no-sound-null-safety” error in Flutter?

The "Could not find an option named no-sound-null-safety" occurring in VS Code.
The “Could not find an option named no-sound-null-safety” occurring in VS Code.

We’re going to learn how to easily fix it in this article.

What causes the “Could not find an option named no-sound-null-safety” error?

The “Could not find an option named no-sound-null-safety” happens in a newer Flutter project using Dart 3.0, because Dart no longer supports unsound null safety.

Unsound null safety was a special Dart/Flutter feature where there are no static checks to ensure that we don’t access nullable variables – variables that may be null.

It allowed developers to migrate their codebase to the default null safety gradually without breaking existing code that depended on null-unsafe libraries.

But from version 3.0 upwards, Dart only supports code using sound null safety.

Fix “Could not find an option named no-sound-null-safety” (general)

To fix the “Could not find an option no-sound-null-safety” Flutter error, remove the --no-sound-null-safety option in your flutter run command.

The "Could not find an option named no-sound-null-safety" occurring in the command line.

Fix “Could not find an option named no-sound-null-safety” in VS Code

To fix the error in Visual Studio Code remove the --no-sound-null-safety option in the Dart: Flutter Additional Args setting.

You can use the Ctrl + , keyboard shortcut to quickly open the Settings page.

[Solved] Cannot find module in Node.js (MODULE_NOT_FOUND)

Are you experiencing the “Cannot find module” or MODULE_NOT_FOUND error in your Node.js project?

This error happens when your IDE can’t detect the presence of a particular NPM package. Let’s see how easy it is to fix.

In this article

1. Ensure NPM package installed

To fix the “Cannot find module” error in Node.js, make sure the NPM package is installed and present in your package.json file.

You can install a package from NPM with the npm i command, for example:

Shell
# NPM npm i nextjs-current-url # Yarn yarn add nextjs-current-url # PNPM pnpm add nextjs-current-url

After installation, the package will included under the dependencies field in package.json

package.json
{ ... "dependencies": { ... "nextjs-current-url": "^1.0.1" ... } ... }
Installed NPM packages are in the package.json dependencies key

You can also install the package as a development dependency, which indicates that the package is only used for development, and won’t be needed by the app itself. Packages like nodemon and ts-node fit this category:

Shell
# NPM npm i -D ts-node # Yarn yarn add -D ts-node # PNPM pnpm add -D ts-node

It will be part of devDependencies in package.json after installation:

package.json
{ ... "devDependencies": { ... "ts-node": "^10.9.1" ... } }

2. Install package again

To fix the MODULE_NOT_FOUND error in Node.js, trying installing the package in your project once again, even if you did so earlier:

Shell
# NPM npm i -D try-catch-fn # Yarn yarn add try-catch-fn # NPM yarn add try-catch-fn

3. Reinstall all packages

Try removing the NPM packages installed in your project and reinstalling them again, to fix the “Cannot find module” error.

You can do this with the following command sequence:

Shell
# NPM rm package-lock.json rm node_modules -r npm cache clear npm install # Yarn rm yarn.lock rm node_modules -r yarn cache clean yarn install # PNPM rm pnpm-lock.yaml rm node_modules -r pnpm store prune pnpm install

npm cache clear helps to rid the package manager cache of any corrupted module files.

4. TypeScript: Install type definitions

The MODULE_NOT_FOUND error will occur when you import a package that doesn’t have any detected type definitions into a TypeScript file.

If it’s a core Node.js module like http or fs, you may need to add "node" to compilerOptions.types in your tsconfig.json file:

tsconfig.json
{ // ... "compilerOptions": { // ... "types": [ "node" ] // ... }, // ... }

If it’s a third-party module, installing the type definitions from NPM should help. For example:

JavaScript
npm i @types/express

5. Ensure package.json main file exists

You may encounter the “Cannot find module” error in Node.js if the main field of your package.json file doesn’t exist.

The file in the package.json main field doesn't exists.

You can also try the npm link command on the package to fix the MODULE_NOT_FOUND error, for example:

Shell
npm link create-react-app npm link webpack

npm link is a command that connects a globally installed package with a local project using a symbolic link.

It enables working on a package locally without publishing it to the npm registry or reinstalling it for every change. Executing npm link in the package directory establishes a symbolic link in the global node_modules directory, directing to the local package.

Afterwards, npm link <package-name> can be used in the project to link the global package with your local project.

7. Ensure correct NODE_PATH

In older Node.js versions, you may be able to fix the “Cannot find module” error by setting the NODE_PATH environment variable to correct node_modules installation folder.

NODE_PATH is a string of absolute paths separated by colons used by Node.js to locate modules when they can’t be found elsewhere.

It was initially created to enable the loading of modules from different paths when there was no defined module resolution algorithm.

And it’s still supported, but it’s not as important anymore since the we’ve established a convention for finding dependent modules in Node.js community.