Discover the best way to traverse a map in Typescript: Which is the preferred method - for...in, for...of, or

Currently, I am grappling with understanding the syntax required to iterate through a map in Typescript. All the keys in this particular map are strings, while the values associated with them consist of arrays of strings.

Below is an excerpt of the sample code:

let attributeMap: Map<string, string[]> = new Map<string, string[]>();

// Sample data
let sampleKey1 = "bob";

// Filling up the map
let value: string[] = attributeMap.get(sampleKey1) || [];
value.push("clever");
attributeMap.set(sampleKey1, value);

value = attributeMap.get(sampleKey1) || [];
value.push("funny");
attributeMap.set(sampleKey1, value);


// Attempting to loop through the map
for (let key in attributeMap) {
    console.log(attributeMap.get(key));
    console.log("WE'RE IN THE MAP!");
}

console.log("done");

Upon running this code as it stands, only "done" gets displayed. Nothing from within the map is printed, and neither does the message "WE'RE IN THE MAP" appear. It seems that the for loop isn't being executed at all. Can anyone shed light on why this is happening and provide insights on how to rectify this issue?

Answer №1

When you assign keys to Maps, the keys are not externally visible on the Map itself - they are stored internally within the Map structure and can only be accessed using specific iteration methods provided by Maps. The for..in loop is designed to iterate over properties that are directly defined on an object or its prototypes.

If you want to iterate over a Map, you should use a method like this instead:

for (const [key, value] of attributeMap.entries()) {
  console.log(key, value);
}

The for..in loop is more suitable for normal objects where key-value pairs are stored as properties directly on the object, rather than for Maps which handle data differently.

When a property is assigned directly on an object, the syntax typically looks like this:

someObj.someProp = 'someVal';

This assigns the someProp property to the someObj object.

However, Maps store their data internally within the [[MapData]] internal slot of the Map, rather than as separate properties on the Map object.

As a thought experiment, in JavaScript, it is technically possible to add a property directly to a Map instance and iterate over it with for..in (essentially treating the map as an object with own properties):

const map = new Map();
map.foo = 'bar';
for (const prop in map) {
  // ...
}

However, this goes against best practices and should be avoided. You should either utilize objects with dot and bracket notation for setting/retrieving properties (along with object methods like Object.entries), or leverage the methods provided by Maps such as Map.get and Map.set for interacting with Map data.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can a single input slider be used to modify several values at once?

Is there a way to adjust multiple values with just one input slider? I've attempted to do so several times without success. My goal is to modify the value of 50,000 at the top of the slider as well as the value of 250k in the unique view's contai ...

Web application error: Karma and Webpack cannot locate Angular controller

After following a blog post on setting up an Angular project with webpack, I used an associated boilerplate on Github. Although the app is functioning properly, Karma seems to have trouble finding the controller it needs to test. // karma.config.js modul ...

What is the best way to retrieve the initial element from an array field obtained through mongoose's populate method?

I am working with a mongodb collection and I am trying to populate a nested field when retrieving data from the database. My goal is to only return specific fields as outlined in the code below. Here is my schema: const hallSchema = new Schema({ hallNam ...

Sort the data returned from a REST API alphabetically in React before performing the map function

Below is the code snippet I've written to fetch an API response and then sort it based on specific criteria, import React, { useEffect, useState } from 'react' function DataList( props ) { const [isLoading, setIsLoading] = useState(fal ...

Is it Possible to Customize the Appearance of a Broken Link Using CSS?

Can you change the color of broken links on your site to distinguish them from working ones? For example, making working links blue and broken links red. If CSS is not an option, is it possible to use JavaScript to detect broken links and style them diffe ...

Explore and Conceal Images with Jquery

Currently, I am utilizing jQuery to showcase images prior to uploading. However, when newer files are uploaded, I wish to either remove or conceal the previous upload files. Here is my jQuery script: $(function() { // Allowing multiple image ...

Create a list with interconnected input fields for duplication

I'm new to javascript and I have a question. I'm working on duplicating a list that has input fields for each option. The duplication is working fine, but the associated input fields are not showing up in the duplicated list. Additionally, I woul ...

Instead of properly addressing the issue, the error message "Cannot read property 'password' of undefined" is being displayed

I'm currently working on creating a user login system using express js and dynamodb. However, I'm facing an issue where the system works fine when logging in with correct email and password, but fails to handle errors when using an incorrect emai ...

Can a client receive a response from server actions in Next.js 13?

I'm currently developing a Next.js application and I've created an action in app/actions/create-foo-action.js. In this server action, I am attempting to send a response back to the client. import { connectDB } from "@utils/database" imp ...

Ajax handling all tasks except for adding HTML elements

Having an issue with my basic "Load More on Scroll" AJAX function. The console is showing that the HTML is being sent back from the request, but for some reason, nothing is being rendered on the page. I must be missing something really simple here. $(wi ...

Creating an Array and declaring its type in Angular 5 using TypeScript

My goal is to create an array from a declared type. I can achieve this using enums, like so: export enum Day { SU = 'su', MO = 'mo', TU = 'tu', WE = 'we', TH = 'th', FR = 'fr& ...

Having trouble retrieving the data property from the parent component within the child component slot

I am facing an issue with my Vue components. I have a rad-list component and a rad-card component. In the rad-list component, I have placed a slot element where I intend to place instances of rad-card. The rad-card component needs to receive objects from t ...

Is it possible to combine the existing request parameters with a new parameter in JSP/JSTL/JQuery?

Here is a sample URL: http://127.0.0.1:8080/admin/seller?email=tim%40example.com Below is a snippet of JSP code: <a class="btn btn-primary ${page==pages||pages==0?'disabled':''}" href="?page=${page + 1}">Next</a> I am ...

What is the best way to execute Jest tests concurrently using the VSCode extension?

Running the Jest tests in band is essential to prevent errors from occurring. However, I am unsure of how to resolve this issue. The tests run smoothly when executed through the command line. ...

A guide on getting the POST method to function with router.post in ExpressJS

I'm currently learning how to create a web application by following a helpful tutorial. The main focus of the app is on creating posts and allowing users to comment on them. I have successfully set up the POST method for creating posts, but I am facin ...

The data type '{}' cannot be assigned to the type 'WebElement'

Background: I am in the process of updating the end-to-end tests to utilize async/await functionality. However, when attempting to modify the function (with a return type promise.Promise < WebElement>) to be asynchronous and calling it from the test, ...

Utilizing only JavaScript to parse JSON data

I couldn't find a similar question that was detailed enough. Currently, I have an ajax call that accesses a php page and receives the response: echo json_encode($cUrl_c->temp_results); This response looks something like this: {"key":"value", "k ...

typescript loop with a callback function executed at the conclusion

I am struggling with this code and it's driving me crazy. addUpSpecificDaysOfWeek(daysInMonth: any, callbackFunction: any){ var data = []; var that = this; daysMonth.forEach(function(day){ that.statsService.fetchData(that.userid, d ...

The image placeholder is missing

This is my custom Results component: This is my custom Thumbnail component: `import React from "react"; const Thumbnail = ({ result }) => { return ( <div> <h1>Thumbnail</h1> </div> ); }; export default Thumb ...

Radio Button Fail to Work as Expected due to Missing Attribute

I've attempted various suggested solutions for this issue, such as using the required attribute on one input and setting it to "required." I'm currently unsure of the next steps to take. Any advice on resolving this problem would be greatly appre ...