Q:

Angular pass and validate input as a Map

I have an input text where the user has to enter a string in Json format, so for example:
    "test":"value",
    "test2":"value2"

When submitting the input, I want to use it as a Map and pass it to my endpoint. What is the correct way to write values in the input so that I can create a Map? If I pass this input, the Map is not created correctly.
What I did was:
variables:Map = myInput;

or
 let variables:Map<String,any> = new Map(myInput);

and then tried to iterate through keyset, but it didn't work. How can I create a Map from a string input and check if is a correct Map? What is the correct syntax for the input string to be considered as Map?

A:

You can use JSON.parse() to parse the input text and when it corresponds to an Object you can easily transform it to a Map by using Object#entries():
const map = new Map(Object.entries(JSON.parse(inputValue)));

Note that Object#entries() is a es2017 feature. Make sure to include es2017 in the lib section of tsconfig.json:
{
  "compilerOptions": {
    ...
    "lib": [
      ...,
      "es2017"
    ]
}

This is a minimal example of a reactive forms validator to check if the JSON code is valid and corresponds to an object:
const jsonValidator: ValidatorFn = (control: AbstractControl) => {
  try {
    const obj = JSON.parse(control.value);
    if (typeof obj !== 'object' || Array.isArray(obj)) {
      throw new TypeError('Top level node should be an object');
    }
  } catch (error) {
    return {
      parseError: error,
    };
  }
  return null;
};

Regarding the explicit typing of the Map: if you want to accept only some types of values in the code, you can add some checks in validation:
if (Object.values(obj).some(v => /* Check value type */)) {
  throw new TypeError('Values should be ...');
}

Checking the keys wouldn't make mush sense since in JSON they can only be strings.
Here is a full example: https://stackblitz.com/edit/angular-dnmfrg

