Matthew Tyson
Contributing Writer

Frequently sought solutions for JavaScript

You have questions, and we have answers. Here are 10 things newer developers often donโ€™t know how to do with JavaScript, with tips and code to help you figure it out.

Too Many Questions. Pile of colorful paper notes with question marks. Closeup.
Credit: StepanPopov / Shutterstock

Youโ€™ve heard of the FAQ, which is typically a list of frequently asked questions on some topic or another. A twist on that idea, the FSSโ€”for frequently sought solutionsโ€”lists solutions to some of the most common pleas for help. These tend to go beyond โ€œnewbieโ€ questions and address real-life issues that bedevil programmers.

Here are 10 issues that come up again and again for developers working with JavaScript, with quick tips and code samples to help you resolve them.

Doing things with arrays

One thing programmers have to do all the time is manipulate arrays of data. This data can be objects, numbers, or strings. You get it from all kinds of places and you do all kinds of things with it: order it, organize it, break it into smaller chunks, and so on.

There are many ways to accomplish the things you need to do with arrays, including classic imperative loops. There isnโ€™t really a right way. However, modern JavaScript gives you a set of incredibly handy functional operations that often provide a concise and streamlined way to do what needs doing. You just have to keep them in mind and know which functional operation to reach for when the time comes.

Consider this array:


const products = [
  { id: 1, name: "Apple", price: 1.99, inStock: true },
  { id: 2, name: "Banana", price: 0.79, inStock: false },
  { id: 3, name: "Orange", price: 2.49, inStock: true },
];

If we wanted to filter for only products in stock and sort them by ascending price, we could do this:


const availableProducts = products.filter(product => product.inStock)
  .sort((a, b) => a.price - b.price);

availableProducts now holds only those objects where inStock is true, and the list is sorted by price. The methods filter and sort are both built-in and take functions as arguments. (These are โ€œhigher-order functions,โ€ a hallmark of functional programming.)

Each functional argument takes the element(s) to operate on and then does its work based on that. In the case of filter, if the function returns true, the element is kept in the resulting array. In sort(), two arguments are provided as the algorithm moves over the array. If the result is negative, the first item is sorted first and vice versa. (If 0 is returned, the items are equal.)

Manipulating the DOM

Although reactive frameworks are often used for working on the DOM (the document object model that represents the user interface and lets you change it) developers still need to directly interact with the DOM using JavaScript.

DOM manipulation boils down to two basic things: reacting to events and changing elements and properties. Consider this example:


<!DOCTYPE html>
<html>
<body>
  <h1 id="heading">Welcome to our website!</h1>
  <button id="change-button">Change Heading</button>

  <script>
    const changeButton = document.getElementById("change-button"); 
    changeButton.addEventListener("click", function(event) { 
      const clickedElement = event.target;  
      clickedElement.style.color = "red"; 
      const heading = document.getElementById("heading"); 
      heading.textContent = "This heading has been changed!";
    });
  </script>
</body>
</html>

Here we have a simple HTML page, with a title (h1) and a button (button). It creates a DOM tree where the <h1> and <button> elements are nested inside the <body>. Also in there is the <script> tag that executes some JavaScript.

The JavaScript grabs the button element by ID, using the document.getElementById("change-button") function.

On the button, we set an event listener using addEventListener. This is the fundamental mechanism for adding reactivity to a page. There are many event types. In our case, we want to respond to the button click using "click". The second argument lets us provide a callback function.

The callback function receives a single argument, which we name event. It has several properties we can use but the main one we want is target. That holds the element that was clicked. We use it to change the button style color to red.

To finish, we grab the h1 heading element by ID and change its text. The text and color changes are examples of using DOM element attributes.

Asynchronous programming

Modern JavaScript is good at asynchronous programming. Itโ€™s a good thing, too, because you have to do it a lot. The three main mechanisms for asynchronous programming are callbacks, promises, and async/await.

Callbacks are traditional:


let myCallback = function(){
  console.log(โ€œI was called after one second.โ€);
}

setTimeout(myCallback, 1000);

This lets us run the myCallback function asynchronously, in this case, after 1,000 milliseconds. Hereโ€™s how weโ€™d do the same thing using a Promise:


function waitOneSecond() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("I was called after one second.");
    }, 1000);
  });
}

waitOneSecond()
  .then(message => console.log(message))
  .catch(error => console.error(error));

We still have an asynchronous operation, and in fact, an asynchronous callback. But now itโ€™s wrapped in a Promise. This lets us call the then and catch methods to deal with the results without nested callbacks.

Async/await blocks make promises simpler and more declarative. They let you write code to use promises like this:


async function waitOneSecondAsync() {
  try {
    new Promise(resolve => setTimeout(() => console.log("I was called after one second."), 1000));
  } catch (error) {
    console.error(error);
  }
}

console.log(โ€œBeforeโ€);
await waitOneSecondAsync();
console.log(โ€œafterโ€);

If you remove the await from this code, the โ€œbeforeโ€ and โ€œafterโ€ log outputs will happen before the timeout. The await lets you pause until the async operation is doneโ€”similar to using a Promise with a then().

Error handling

Code can raise an exception (also known as throwing an error) at any time to indicate a problem:


throw new Error("Something is not right here.")

This will cause the normal flow of execution to cease, and that call stack to โ€œunwind.โ€ If the stack includes try/catch blocks, the first one encountered will handle the error. Hereโ€™s a compact example:


try{ 
  throw new Error("Something is not right here.") 
} catch(e) { 
  console.log("Got an error: " + e);
}

This will print: Got an error: Error: Something is not right here.

More elaborate error handling is possible, including attempting to recover, retry, or any other number of strategies given the circumstances. We can also define a finally block, which will be called if there is an error or not:


try{ 
  throw new Error("Something is not right here.") 
} catch(e) { 
  console.log("Got an error: " + e);
} finally {
  console.log(โ€œNo matter what, Iโ€™ll print.โ€);
}

When using asynchronous operations with promises, we can use catch() and finally() in a similar fashion. Letโ€™s continue with our timeout example:


function waitOneSecond() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("Network error!"));  
    }, 1000);
  });
}

waitOneSecond()
  .then(message => console.log(message))  
  .catch(error => console.error("Error:", error.message))   .finally(() => console.log("This always executes, regardless of errors."));  

In this case, the catch() and finally() blocks will always execute, because an error is always thrown. In real code, when normal execution doesnโ€™t throw an error, the catch call wonโ€™t happen.

Getting started with objects

Objects are a central part of programming JavaScript. JavaScript even has a built-in notation for describing them, JSON:


let campingSpot = {
  name:  โ€œWillow Creekโ€,
  location: โ€œBig Surโ€
}

Hereโ€™s how to access the properties on the object:


console.log(โ€œWeโ€™re going camping at โ€œ + campingSpot.name);

Objects in JavaScript are not limited to JSON. We can also define behavior in the form of functions (called methods when on an object):


let campingSpot = {
  name:  โ€œWillow Creekโ€,
  describeWater: function(){
    console.log(โ€œVery coldโ€);
  }
}

We are not limited to one-off objects, either. We can also define classes of objects:


class CampingSpot {
  constructor(name, location) {
    this.name = name;
    this.location = location;
  }
    describeWater() {
      console.log("The water at " + this.name + " is very cold.");
    }
}

Now we can create instances of the CampingSpot object at will:


let willowCreek = new CampingSpot("Willow Creek", "Big Sur");
let sunsetStateBeach = new CampingSpot(โ€œSunset State Beachโ€, โ€œSanta Cruzโ€);

Using remote APIs

Accessing APIs hosted on services is another common need in JavaScript programs. APIs provide access to external data and functionalities. Developers often seek solutions to fetch data from remote APIs, parse responses, and integrate them into their applications.

Fortunately, modern JavaScript includes the Fetch API in both client and server environments. This is a simple and direct way to make HTTP calls. For example, hereโ€™s how weโ€™d get the list of Star Wars movies from the SWAPI service:


async function getStarWarsFilms() {
  try {
    const response = await fetch('https://swapi.dev/api/films');
    if (!response.ok) {
      throw new Error(`Error fetching Star Wars films: ${response.status}`);
    }
    const data = await response.json();
    console.log(data.results); 
  } catch (error) {
    console.error("Error:", error);
  }
}

getStarWarsFilms();

Because this is a GET request, we can just use fetch('https://swapi.dev/api/films'). Notice we use await, which I introduced earlier. That lets us pause while the request goes out and the response comes back.

We use the response object to determine if the request was good (an HTTP 200 response), using response.ok.

String manipulation

Strings are fundamental building blocks and used in all kinds of situations. Consider the following string:


const taoTeChingVerse1 = 
  `The Tao that can be told is not the eternal Tao. 
  The name that can be named is not the eternal name. 
  The nameless is the beginning of heaven and earth. 
  The named is the mother of all things,`;

Letโ€™s say we wanted only the first line of the first verse:


const firstLine = taoTeChingVerse1.slice(0, 48);

This says: Give us the substring between the first character (0) and the 48th character, inclusive.

To search for the first occurrence of the word โ€œTao,โ€ enter:


taoTeChingVerse1.indexOf("Tao"); // returns 4

Now, if you want to replace words, you use some simple regex. Here, we replace all occurrences of โ€œtoldโ€ with โ€œspokenโ€:


const newText = text.replace(/told/g, "spoken");

The slashes indicate a regular expression, which we match on โ€œtold.โ€ The suffix g indicates โ€œglobal,โ€ meaning all occurrences. The second argument to replace() is the token to swap in. (We wind up with โ€œThe Tao that can be spoken is not the eternal Tao.โ€)

If we need to concatenate two strings, a simple plus (+) operator will do the trick:


let fullVerse = taoTeChingVerse1 + โ€œHaving both but not using them, Think of them as the constant.โ€);

And, you can always count the string length with:


fullVerse.length; // return 261

Converting JSON objects to strings

Another common need is to take a JSON object and make it a string, or vice versa. Hereโ€™s how to take a live JSON object and make it a string:


let website = {
  name: โ€œInfoWorldโ€,
  url: โ€œwww.infoworld.comโ€
}

let myString = JSON.stringify(website);

And hereโ€™s how to take the string and return it as a JSON object:


JSON.parse(myString);

Simple date operations

There is a lot you can do (and must do) with JavaScriptโ€™s built-in Date object.

To start, you can get todayโ€™s date, like so:


const today = new Date();

And you can get its constituent parts like this:


console.log(today.getFullYear());  // Get the year (e.g., 2024)
console.log(today.getMonth());    // Get the month (0-indexed, e.g., 4 for May)
console.log(today.getDate());     // Get the day of the month (e.g., 21)
console.log(today.getHours());    // Get hours (e.g., 13 for 1 PM)
console.log(today.getMinutes());  // Get minutes (e.g., 27)
console.log(today.getSeconds());  // Get seconds (e.g., 46)

Hereโ€™s how to get seven days in the future:


date.setDate(date.getDate() + 7);

Creating, finding, and counting numbers

JavaScript today is pretty good with numbers. It natively handles most numbers and offers a built-in library, Math, for extra power.

You can create numbers:


let age = 30;
let pi = 3.14159;
let billion = 1000000000;

Or convert from a string:


let convertedNumber = Number(โ€œ42โ€);

Normal operations behave in obvious ways:


let addition = pi + 3; // addition now equals 6.14159

You can round numbers quickly:


Math.ceil(pi); // round to nearest upper integer (4)
Math.floor(pi); // round to lowest int (3)

Find the largest number:


Math.max(100, 5, 10, 73);  // returns 100

If you start with an array, you can use the spread operator:


let numbers = [100, 5, 10, 73];
Math.max(...numbers); // returns 100

Finally, hereโ€™s how to check for evenness:


let isEven = 10 % 2 === 0; // true (checks if remainder is 0)

Matthew Tyson
Contributing Writer

Matthew Tyson is a contributing writer at InfoWorld. A seasoned technology journalist and expert in enterprise software development, Matthew has written about programming, programming languages, language frameworks, application platforms, development tools, databases, cryptography, information security, cloud computing, and emerging technologies such as blockchain and machine learning for more than 15 years. His work has appeared in leading publications including InfoWorld, CIO, CSO Online, and IBM developerWorks. Matthew also has had the privilege of interviewing many tech luminaries including Brendan Eich, Grady Booch, Guillermo Rauch, and Martin Hellman.

Matthewโ€™s diverse background encompasses full-stack development (Java, JVM languages such as Kotlin, JavaScript, Python, .NET), front-end development (Angular, React, Vue, Svelte) and back-end development (Spring Boot, Node.js, Django), software architecture, and IT infrastructure at companies ranging from startups to Fortune 500 enterprises. He is a trusted authority in critical technology areas such as database design (SQL and NoSQL), AI-assisted coding, agentic AI, open-source initiatives, enterprise integration, and cloud platforms, providing insightful analysis and practical guidance rooted in real-world experience.

More from this author